Sometimes we want automatize a script on the cloud or an on-premise server without using local task schedulers. To achieve this, lets use containers and a cron job!
A Docker is a tool that allows us to deploy and run applications using containers. A container has all the parts of the environment that you need to run your software, such as libraries and dependencies in our R script.
The advantage of Docker is its portability, meaning that you can create your environment and deploy it on any cloud or another computer.
- Create a directory (folder) for the project.
- Inside the new directory Create a Dockerfile, a file that will have all the necessary instructions to create the R environment, download its dependencies and packages to execute the script.
1 2 3 4 5 6 7 8 9 10 11 FROM rocker/tidyverse:latest ##We copy the file inside the container COPY /install_packages.R /install_packages.R COPY /script_to_run.R /script_to_run.R ## We install the packages RUN Rscript /install_packages.R ## We execute the script CMD ["Rscript", "script_to_run.R"]
In this case we’ll use the last tidyverse docker image configured by rocker. If you want an specific R version you have to specify it after :
- Create R script named install_packages.R that will be called by the Dockerfile when building to download the packages that we will be using in our task.
1 2 3 4 5 6 install.packages("tidyverse") install.packages("xts") install.packages("zoo") install.packages("tidyquant") install.packages("timetk") install.packages("lubridate")
- Create your script. Here I use the function suppressPackageStartupMessages to get a cleaner terminal result. In this case we are getting daily returns for the selected stocks on the vector FAANG.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 suppressPackageStartupMessages(library(tidyverse)) suppressPackageStartupMessages(library(xts)) suppressPackageStartupMessages(library(zoo)) suppressPackageStartupMessages(library(tidyquant)) suppressPackageStartupMessages(library(lubridate)) suppressPackageStartupMessages(library(zoo)) suppressPackageStartupMessages(library(timetk)) initial_date <- floor_date(Sys.Date() - weeks(1), "week") FAANG <- c("AAPL", "GOOG", "AMZN", "NFLX") xtsFAANG_daily_returns <- FAANG %>% tq_get(get = "stock.prices", from = initial_date, to = Sys.Date()) %>% group_by(symbol) %>% tq_transmute(select = adjusted, mutate_fun = periodReturn, period="daily", type="arithmetic") %>% select(symbol, date, daily.returns) %>% spread(symbol,daily.returns) %>% tk_xts(silent = TRUE) xtsFAANG_daily_returns[nrow(xtsFAANG_daily_returns), ]*100
- Go to your proyect directory on the terminal.
1 cd ../Documents/project_directory
- Build the container
1 sudo docker build -t auto_script .
Its going to take a while building the tidyverse image. Don’t forget the . at the end of the command. This tells our terminal that the Dockerfile its inside the proyect directory and its named Dockerfile.
- Run the container
1 run sudo docker run auto_script
You should be able to see this result on your terminal.
If you want the script to be run on a daily basis you can create a bash shell script file named process.sh that runs the container on a cron job.
1 2 #!/bin/sh sudo docker run auto_script
Configure the cron job by opening contrab -e in the terminal and setting up the job like this:
1 0 18 * * 1-5 process.sh > process.txt
This commands will run process.sh every weekday at 6:ooPM and write the log to the file process.txt.
This is a nice webpage to configure your cron job given your specific needs https://crontab-generator.org/
Finally, this steps can be taken on a mac or linux computer or a VM instance with those operating systems.