# How to write a Docker file

### Build a base image

The usual way to get started building up a docker image is to use a base image. A base image is a pre-build Docker image that already has everything needed to run the container. We can then build our image on top of the base image.

#### Which images are available

You can check which images are [available in Sandbox](https://docs.finngen.fi/working-in-the-sandbox/quirks-and-features/docker-images/containers-available-to-sandbox). Building of a docker file should be conducted outside the sandbox. You can do this e.g. using google VM. After the docker file is done see instructions [how to get your image to Sandbox](https://docs.finngen.fi/working-in-the-sandbox/quirks-and-features/docker-images/packages-conflicting-other-packages-in-current-ivm).

Our example for a Docker file is an [Docker file for basic Saige](https://github.com/FINNGEN/saige-pipelines/blob/master/docker/basic_Saige).

### Writing a Docker file

#### FROM

Writing a Docker file starts with FROM command. With FROM a base image is selected. You can select a specific version using version number or select latest version using *latest* definition

```
# example of FROM commands
FROM ubuntu:16.04
FROM ubuntu:latest
```

#### ENV

Environmental variable is set with ENV command with a given name (e.g. ENV my\_env\_name 1.1). Environmental variables will be accessible by any processes running inside your image. For example setting environmental variable named R\_VERSION and desired version number

```
ENV R_VERSION 3.5.1
```

#### WORKDIR

WORKDIR command creates a directory of given name under current directory and use it as a working directory. All commands executed will use this working directory. For example, commands producing files will send produced files to this working directory. Docker file is read and executed line by line starting from the top. If folders need to go to another location as image building proceeds same WORKDIR command can be repeated. For example creating a working directory named tmp

```
WORKDIR /tmp
```

#### RUN

Run command is used to execute packages inside the image. For example, to update and install dependences

```
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    cmake
```

With RUN command we can also install softwires from source and send them to environmental variables as e.g. in our example of [basic Saige](https://github.com/FINNGEN/saige-pipelines/blob/master/docker/basic_Saige)

```
# Install R from source
RUN curl -O https://cloud.r-project.org/src/base/R-3/R-${R_VERSION}.tar.gz \
    && tar xvzf R-${R_VERSION}.tar.gz
```

**Example:** See Samuel Jones user case of Docker image from [FinnGen Users' meeting video 7th Sep 2021](https://www.finngen.fi/en/members/recordings/finngen-data-users-meeting-7th-september-2021).

For further information see [Docker guides page](https://docs.docker.com/go/guides/)

Tutorial video [How to build up a docker image](https://www.youtube.com/watch?v=iqqDU2crIEQ)

Instructions [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) and [How do you write a Dockerfile?](https://www.educative.io/edpresso/how-do-you-write-a-dockerfile)
