Docker Basics for Data Apps
Tags: shiny, rstats
Published: 2021-05-07 19:46:44

<p><em>By: <a href='https://hosting.analythium.io/author/peter/'>Peter Solymos</a></em></p><p>Containers provide portability, consistency, and are used for packaging, deploying, and running <strong>cloud-native</strong> data science applications. <a href="https://www.docker.com/">Docker</a> is the most popular virtualization environment to deliver software in containers. Docker is also well supported by the <a href="https://github.com/rocker-org/rocker">R community</a>. Among the many use cases, Docker is most commonly used to deploy <strong>reproducible workflows</strong> and to provide isolation for <strong>Shiny apps</strong>. In this post we review the basics of working with Docker to lay the foundation for "dockerizing" data applications coming up in the next post.</p><h2 id="what-is-docker">What is Docker</h2><p>Note: this post relies heavily on the Docker documentation to provide an easy-to-reference summary of the main terms and concepts.</p><blockquote>Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. – <a href="https://docs.docker.com/">Docker documentation</a></blockquote><p>Containers <strong>bundle</strong> their own software, libraries and configuration files and are <strong>isolated</strong> from one another. Containers are the <strong>run-time</strong> environments or <strong>instances</strong> defined by <strong>container images</strong>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://hosting.analythium.io/content/images/2021/04/vm-vs-container.png" class="kg-image" alt="Virtual machines vs. containers" loading="lazy" width="2000" height="1124" srcset="https://hosting.analythium.io/content/images/size/w600/2021/04/vm-vs-container.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/04/vm-vs-container.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/04/vm-vs-container.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/04/vm-vs-container.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>Virtual machines vs. containers / © Analythium</figcaption></figure><h2 id="install-docker">Install Docker</h2><p>To download and install Docker for your platform of choice, visit the <a href="https://docs.docker.com/get-docker/">Docker download page</a> and follow the instructions.</p><h2 id="docker-concepts">Docker concepts</h2><p>Let's review the most important concepts. The image below illustrates how all the Docker related concepts all fit together:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://hosting.analythium.io/content/images/2021/04/architecture.png" class="kg-image" alt="Docker architecture" loading="lazy" width="2000" height="1124" srcset="https://hosting.analythium.io/content/images/size/w600/2021/04/architecture.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/04/architecture.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/04/architecture.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/04/architecture.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>Docker architecture / © Analythium</figcaption></figure><h3 id="docker-engine">Docker Engine</h3><p>The Docker Engine is a client-server application that includes a <strong>server</strong><em> </em>(a long-running daemon process that listens to API requests, <code>dockerd</code>), a <strong>application programming interface</strong> (<a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> API, specifies the interface that programs can use to talk to the daemon), and a <strong>command line interface</strong> (CLI, the client side, <code>docker</code>).</p><p>The CLI uses the REST API to control or interact with the Docker daemon. The daemon creates and manages <strong>Docker objects</strong>, such as <strong>images</strong>, <strong>containers</strong>, etc.</p><h3 id="docker-registries">Docker registries</h3><p>A Docker registry stores Docker <strong>images</strong>. <a href="https://hub.docker.com/">Docker Hub</a> is a public registry and Docker is configured to look for images on Docker Hub by default. There are many other registries, or users can have their own private registry.</p><h3 id="docker-images">Docker images</h3><p>An image is a <strong>read-only template</strong> with instructions for creating a Docker <strong>container</strong>. An image can be based on another image with additional customization on top of this so called <strong>base image</strong>.</p><h3 id="docker-containers">Docker containers</h3><p>A container is a <strong>runnable instance</strong> of an image. Users can create, start, stop a container using the Docker API or CLI. It is also possible to connect a container to networks or attach storage to it.</p><p>By default, a container is <strong>isolated</strong> from other containers and the host machine. The degree of isolation can be controlled by the user, and depends on whether it is connected to networks, storage, other containers, or the host machine.</p><h3 id="dockerfile">Dockerfile</h3><p>Docker builds images by reading the <strong>instructions</strong> from a <code>Dockerfile</code>. A <code>Dockerfile</code> is a text document that contains all the commands to assemble an image using the <code>docker build</code> CLI command. You will learn more about the <code>Dockerfile</code> as part of the worked Shiny example later.</p><h3 id="cli-commands">CLI commands</h3><p>The most common Docker CLI commands are:</p><ul><li><code>docker login</code>: log into a Docker registry</li><li><code>docker build</code>: build a Docker image based on a <code>Dockerfile</code></li><li><code>docker push</code>: push a locally built image to a Docker registry</li><li><code>docker pull</code>: pull an image from a registry</li><li><code>docker run</code>: run a command in a new container based on an image</li></ul><p>You will learn more about these commands in an upcoming post.</p><h2 id="summary">Summary</h2><p>Learning Docker seems daunting at first, but it is an incredibly powerful piece of technology once you get the hang of it. It is also the building block of the modern web.</p><h2 id="further-reading">Further reading</h2><ul><li><a href="https://docs.docker.com/get-started/">Get started with Docker</a></li><li><a href="https://www.freecodecamp.org/news/docker-simplified-96639a35ff36/">Docker simplified</a></li><li><a href="https://docker-curriculum.com/">Docker for beginners</a></li><li><a href="https://docs.docker.com/glossary/">Docker glossary</a></li><li><a href="https://docker.farhan.info/">The Docker Handbook</a></li></ul>