> For the complete documentation index, see [llms.txt](https://teachersmanual.firstdraft.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://teachersmanual.firstdraft.com/docker-essentials.md).

# Docker Essentials

Docker is a collection of tools that makes it easier to create, deploy, and run applications.

Under the hood, one of the reasons Gitpod is able to create the virtual computers so quickly is because they use Docker to help create the workspaces we use.

[Install Docker](https://docs.docker.com/get-docker/)

[Sign Up for Docker Hub Account](https://hub.docker.com/signup)

## Basic Parts of Docker

For the basic usage we need to know about two or three parts of Docker, the `Dockerfile`, Docker Images, and Docker Containers.

### `Dockerfile`

A `Dockerfile` is essentially a file with a set of instructions to install an Operating System and any command line tools or packages that you want on a "virtual computer".

You can think of a `Dockerfile` as a recipe for a computer. It’s the list of ingredients in a specific order.

There are Docker specific commands that you need to use when crafting a `Dockerfile`. It’s not like learning a new language, however. Most of the time, the majority of a `Dockerfile` just has a bunch install commands like

```bash
apt-get install
pip3 install -r requirements.txt
```

### Docker Image

A `Dockerfile` can be used to create an "Image", which is essentially a compiled version of the `Dockerfile`.

If the `Dockerfile` is a recipe, then building a Docker Image is like going to the store, buying all the ingredients, and pre-heating the oven.

From a Docker image, you can very quickly create however many "containers" you want.

### Docker Container

A Docker Image, can be used to create a "Container", which is the actual "virtual computer" that you can interact with run/develop code on.

They behave identically to a Gitpod workspace. You can stop and start them, run programs, or even download more files to them.

I won't go into how you run containers outside of Gitpod for now. But conceptually I think it’s helpful to know how a Gitpod workspace relates to a Docker Image.

## How to use a custom Docker Image with Gitpod

You can set up various Gitpod settings using a `.gitpod.yml` file in the root of your repository. This includes choosing a custom Docker image to use.

```yml
# .gitpod.yml
image: IMAGE_NAME
```

For example, since Gitpod doesn’t come with `R` pre-installed, we used a Docker image that had `R` installed.

```yml
# .gitpod.yml
image: rocker/r-base
```

Gitpod will take care of fetching the Image and caching it and creating the container.

## How to Write a `Dockerfile`

There are two main steps for writing a basic `Dockerfile`.

### Step 1: Specify a Starting Image

This is required as the first instruction in a `Dockerfile`. Used to specify the starting point. You need to specify a pre-existing Docker image. Docker has created a variety of Images with different Operating Systems including versions that you can choose from. If Docker hasn’t made one, usually someone else has and they’ve made it available to use for free.

You specify the starting image by using the `FROM` command with the name of the Image[1](#1-name-of-the-image).

For example if we wanted to start from the `R` Docker image,

```
# Dockerfile
FROM rocker/r-base
```

### Step 2: Everything Else

Generally "everything else" will be mostly just installing packages or dependencies, but sometimes this might also mean copying a data file[2](#2-copying-a-data-file) that you want to have in your workspace when you’re running your script.

Use the `RUN` command to perform any Bash command you would normally use in a Terminal.

For example, if we want to install `git` in the image we create we can this.

```
# Dockerfile
FROM rocker/r-base

RUN apt-get update
RUN apt-get install -y git
```

That’s all we need for the `Dockerfile`. Next is to create the Image.

## How to Create a Docker Image

Assuming you have the Docker CLI installed, move to the directory of the `Dockerfile` , pick an image name, and run

```bash
docker build -t my-image-name .
```

The `-t` flag "tags" the built Image with a name.

If anything goes wrong during the build process, you’ll get an error message and can try again.

Gitpod can also build images for you. In the `gitpod.yml` file you can specify a `Dockerfile` instead of an Image.

```yml
# .gitpod.yml
image:
  file: Dockerfile
```

The downside of this is that you have to wait for Gitpod to build the image, which can sometimes take a long time.

## Storing a Docker Image in the Cloud

Just like GitHub, there’s Docker Hub where Docker images are stored.

To push an Image to our Docker Hub, we can run

```bash
docker push jelaniwoods/my-cool-image
```

and that’s about it!

Now I can update my `.gitpod.yml` to use *my* image

```yml
# .gitpod.yml
image: jelaniwoods/my-cool-image
```

and when I create a new Gitpod workspace, it will download and use my image from Docker Hub.

***

#### 1 Name of the image

Images should be hosted in the cloud on Docker Hub whenever possible. When naming Images, follow the format: `your-username`/`chose-a-name`.

#### 2 Copying a data file

I mostly end up copying files that have my project's dependencies, like `requirements.txt` in Python, `Gemfile` in Ruby, `package.json` for JavaScript. So to pre-install all the packages in my `requirements.txt` on a Docker image with

```
# Dockerfile
# ...

# Copy requirements.txt from my repository and place it in the /dependencies folder in my Docker image
COPY requirements.txt /dependencies/requirements.txt

RUN pip3 install -r /dependencies/requirements.txt
```
