Far from being a Docker expert, I nevertheless tried recently to build my own Docker containers, as it makes it so much easier to transfer apps between operating systems (os). However, every start is challenging and hence, I felt a documentation of my first steps might come in handy for people eager to containerize away. I am working with a mac os and have build a container for a R-shiny app. This has been originally been published on my website
What is Docker
Docker was introduced to the public in 2013 at PyCon in Santa Clara (I recommend you watch the 5 min. talk here).
Docker software is aiming to facilitate project implementation, putting your applications into Linux-containers (containerization), which will include all the libraries that your app requires. It is similar to a virtual machine, however, has the advantage of not simulating a whole computer operating system, but only the necessary bits. Hence, docker containers outperform VMs.
Some phrase explanations: A container is an isolated software environment which runs the application. It holds a static docker-image, which contains everything that your app needs, e.g code, libraries and configuration files. The source code for your images is stored in Dockerfiles. Assuming everybody likes to bake: The image is the recipe, the container is the cake.
Docker vs. virtual machines
Each virtual machine holds a copy of a full operating system that its applications are using. Therefore, VMs will take up a lot of space and memory, consequently, being computationally expensive and slow. Docker, on the other hand is build upon the host OS, hence does not need an additional OS and can excel in performance and storage requirements.
Fig. 1: On the left applications (A-C) deployed using Virtual Machines. On the right applications deployed with docker containers. Docker uses the host OS and makes the additional Guest OS obsolete.
Why use Docker
One of the biggest advantages for me as an R-user is the stability and reusability of R-versions and corresponding packages. Whereas you often run into issues with libraries no longer supported by your current R version, docker stores the required R environment and the used libraries.
Additionally, Docker is easy to deploy and saves you the hustle of installation and setting up your webapps on different machines.
How-to-guide for your first Docker Image
(this guide focuses on mac os)
-Install docker
-Open docker (click on icon)
-Open terminal and check:
docker info #basic system information (how many containers, images, running etc.)
Before you build your own container with an app, have a look at the container provided by docker
-Log into your Docker account and run the hello-world container
docker run hello-world #runs hello-world container example from docker
because the hello-world image above is not found locally, it will be pulled from the Docker Hub. If you see the text above it worked.
-To view your docker images:
docker images #displays the images on your machine
Create a local docker container for your app
-Create a directory and go there:
mkdir DockerRep # created new directory
cd DockerRep # change directory
-Create your app and a run file:
app.R (I have created that app in another blog)
app_run.R (see content below):
require(shiny) #loads shiny package
shiny::runApp("app.R", launch.browser = FALSE, port = 8080, host = "0.0.0.0") #runs shiny app in port 8080 localhost
-Create a Dockerfile (I am using vi commandline-editor. Feel free to use anything you like)
Dockerfile (below):
#build an image on top of the base image for r version 3.5.1 from [rocker] (https://hub.docker.com/r/rocker/r-ver/~/dockerfile/)
FROM rocker/r-ver:3.5.1
#install necessary libraries
RUN R -e "install.packages(c('ggplot2','shiny'))"
#copy the current folder into the path of the app
COPY . /usr/local/src/app
#set working directory to the app
WORKDIR /usr/local/src/app
#set the unix commands to run the app
CMD ["Rscript","app_run.R"]
So in my ~/path/DockerRep/ I have three files: 1) app.R; 2) app_run.R; 3) Dockerfile.
Finally, read the recipe and bake the cake, or just build the image and run the container:
#build an image named "mydockerapp"(needs to be lower case)
docker build -t mydockerapp .
#run the image "mydockerapp" in the container "DOCKERapp" in port 8080
docker run --name DOCKERapp -p 8080:8080 mydockerapp
Calling https:/localhost:8080 in your webbrowser you can now use your containerized shiny app. Additionally you'll be able to ship your container to a server, another mashine etc. The R enivironment in your container will remain the same and your app will be running smoothely, even if you happen to update your R version.
Few further notes:
If you want to view which containers are running and have run:
docker ps #running
docker ps -a #have run
Be aware that everytime you use docker run image-name you are creating a new container. Instead you could run docker run -rm image-name, which will ensure the container is removed afterwards.
If you would like to delete containers:
docker rm -f containerName #remove a container
TOP 5 Docker commands
Below is a list of docker commands I found usefull. Vote for your favorite command in the comments section.
1- docker run -t -i ubuntu /bin/bash #running an ubuntu machine
2- docker ps #are there still container running
3- docker images #display docker images
4- docker build #builds docker images
5- docker rm -f containerName #delete containers you no longer need
Helpful links
https://docs.docker.com/get-started/#docker-concepts (detailed instructions on where to start)
https://docs.docker.com/docker-for-mac/ (docker for mac - get started)
https://ropenscilabs.github.io/r-docker-tutorial/ (some instructions on how to run Rstudio in a container and generally on R and docker)
An Introduction to Rocker: Docker Containers for R
More on Dockerfiles
Docker: have a Ubuntu development machine within seconds, from Windows or Mac
(some instructons on how to building and using a containerised a unix-machine)
Top comments (6)
Your post is a good introduction, but sadly the first sentence is wrong:
You can't transfer containers between operating systems at all. VMs can do that. Why? As you said, docker uses the underlaying operating system (Linux). So it would be better to say "easier to tranfer apps between servers" or something like that.
I know that there are windows containers too, but those are also only able to run in windows.
Hey thanks. Still a lot to learn. I was hoping I could transfer containers between all os.
Actually Docker distributions on Windows or OSX are virtual machines running a Linux kernel. So in practice you can build regular Linux Docker images and run them on the three systems. That's just Linux everywhere under the hood, and you'll have a few caveats due to the hidden virtualization layer (e.g. docker network access from the host).
Yeah, but that still makes the containers run on Linux and not the host operating system.
Good work.
I think you have a good sense of how the stuff works and are needed.
Maybe the correct word was deploy.
It would be something like:
Next steps could be to have a look at volumes and to explore docker-compose. I would advise against swarm though, the minikube / kubernetes direction being a sounder time investment from my point of view.