Create Dockerfile

Last Updated: November 2021

With Docker installed and a basic understanding of how it works under your belt, you are now ready to create a Docker image containing the Tethys Portal with your apps installed. In this tutorial you will create a Docker image with some of the tutorial apps installed. A similar process can be used to create a Docker image for your Tethys Portal.

Prerequisites

Please ensure you have the following prerequisites before continuing:

Project Setup

Before you can start creating the Dockerfile there is some setup that needs to be completed. This includes creating a folder to house all of the artifacts that you will use for the Docker build and acquiring the source code for the apps that will be installed in the Tethys Portal. It will also include setting up a Git repository. An important part of creating Docker projects is knowing how to properly version it version control software, so this tutorial will instruct you which files to commit. Follow these instructions to set up the Docker project.

1. Create New Directory

Create a new directory to house the Dockerfile and other artifacts that will be used for the build.

default
mkdir tethys_portal_docker
cd tethys_portal_docker

Tip

If you are on Windows, we recommend using the Git Bash terminal that comes with Git for Windows when running commands in this tutorial.

2. Create Initial Files

  1. Create the following text files in the tethys_portal_docker directory:

    default
    touch  README.md LICENSE Dockerfile
    
  2. Add the following contents each the files:

    README.md

    markdown
    # Demonstration Tethys Portal Docker Project
    
    This repository demonstrates how to make a Docker image containing a custom Tethys Portal with apps installed. The apps installed are the solutions to several of the Tethys Platform tutorials and include:
    
    * [Dam Inventory](https://github.com/tethysplatform/tethysapp-dam_inventory.git)
    * [THREDDS Tutorial](https://github.com/tethysplatform/tethysapp-thredds_tutorial)
    * [Earth Engine](https://github.com/tethysplatform/tethysapp-earth_engine.git)
    * [PostGIS App](https://github.com/tethysplatform/tethysapp-postgis_app.git)
    * [Bokeh Tutorial](https://github.com/tethysplatform/tethysapp-bokeh_tutorial)
    

    LICENSE

    Choose an open source license from Licenses and Standards | Open Source Initiative. Copy it into the LICENSE file.

    Dockerfile

    Leave this empty for now as it will be discussed in depth in the next steps.

3. Initialize Git Repository

Initialize a new Git repository in the tethys_portal_docker directory. Then add all the files and create the first commit.

default
git init
git add .
git commit -m "First commit"

4. Checkout App Solutions

In this step you'll add the source code of the apps you want to install to the tethys_portal_docker directory so they can be used in the build. Generally, only files in the same directory as the Dockerfile are accessible to use during a docker build operation.

Adding the files to this directory could be as simple as copying the tethyapp-xyz folders into the directory. However, the apps we are installing are available on GitHub, so we can use Git Submodules, which allows you to add a Git repository as a submodule of another Git repository. The advantage of this approach is that as the apps update, we need only pull the latest version in each submodule and then we can build an updated Docker image.

Add the app repositories as Git submodules as follows:

Bokeh App:

default
git submodule add -b master https://github.com/tethysplatform/tethysapp-bokeh_tutorial

Dam Inventory:

default
git submodule add -b advanced-solution https://github.com/tethysplatform/tethysapp-dam_inventory

Earth Engine:

default
git submodule add -b prepare-publish-solution https://github.com/tethysplatform/tethysapp-earth_engine

PostGIS App:

default
git submodule add -b master https://github.com/tethysplatform/tethysapp-postgis_app

THREDDS Tutorial:

default
git submodule add -b plot-at-location-solution https://github.com/tethysplatform/tethysapp-thredds_tutorial

5. Commit Changes

Commit the new submodules configuration that was generated (.gitmodules):

default
git commit -am "Added apps as submodules"

Edit Dockerfile

With the app source code checked out it is time to build out the Dockerfile. A Dockerfile is composed of several different types of instructions. The instructions used in our Dockerfile will be explained as it is built-out, but you can refer to the Dockerfile Reference | Docker Documentation for full explanations of any instructions.

1. Add FROM instruction

All Dockerfiles must begin with a FROM instruction that specifies the base image or starting point for the image. Tethys Platform provides a base image that already has Tethys Platform installed. Add the FROM instruction to the top of the Dockerfile as follows:

default
FROM tethysplatform/tethys-core:latest

Note

The latest portion of the image name is a tag that specifies the latest released version will be used for the build. Alternatively, you can replace the latest tag with either a specific version of Tethys Platform (e.g. 3.3.0) or with the dev tag to use the latest development version. For a list of all available tags see: tethysplatform/tethys-core Tags.

2. Define environment variables

The ENV instruction can be used to specify environment variables that are used during the build and when the container is running. Environment variables are often overridden when creating the container and can be thought of as arguments for a container to configure it for the specific deployment use case. The base Tethys Platform image provides many environment variables, some of which we will use during our build. For a full list of the Tethys Platform image environment variables see Environment Variables.

For this image, define environment variables for the various settings for the apps that will be installed. Add the following lines to the Dockerfile:

default
###############
# ENVIRONMENT #
###############
ENV DAM_INVENTORY_MAX_DAMS="50" \
    EARTH_ENGINE_PRIVATE_KEY_FILE="" \
    EARTH_ENGINE_SERVICE_ACCOUNT_EMAIL="" \
    THREDDS_TUTORIAL_TDS_USERNAME="admin" \
    THREDDS_TUTORIAL_TDS_PASSWORD="CHANGEME!" \
    THREDDS_TUTORIAL_TDS_PROTOCOL="http" \
    THREDDS_TUTORIAL_TDS_HOST="localhost" \
    THREDDS_TUTORIAL_TDS_PORT="8080"

Note

The # character is used to denote comments in Dockerfiles.

3. Add files to image

The ADD and COPY instructions let you copy files into the docker image. The difference between the two is that ADD will automatically decompress archive files (e.g.: .tar.gz) and it can take a URL as the source of the copy (though confusingly if the URL is pointing to an archive, it won't decompress it automatically). It is recommended to use COPY unless you specifically need the extra features of ADD.

Copy the directories containing the app source code to the ${TETHYS_HOME}/apps directory, which is the recommended directory for app source code. Add the following lines to the Dockerfile:

default
#############
# ADD FILES #
#############
COPY tethysapp-bokeh_tutorial ${TETHYS_HOME}/apps/tethysapp-bokeh_tutorial
COPY tethysapp-dam_inventory ${TETHYS_HOME}/apps/tethysapp-dam_inventory
COPY tethysapp-earth_engine ${TETHYS_HOME}/apps/tethysapp-earth_engine
COPY tethysapp-postgis_app ${TETHYS_HOME}/apps/tethysapp-postgis_app
COPY tethysapp-thredds_tutorial ${TETHYS_HOME}/apps/tethysapp-thredds_tutorial

4. Add files for custom theme

  1. Download the following images to use in the custom theme for the Tethys Portal:

  2. Create a new folder called images in the tethys_portal_docker directory:

    default
    mkdir images
    
  3. Add the downloaded images to the new images directory.

  4. Add the following lines to the Dockefile to add the images to the container image in the tmp directory (they will need to be moved at runtime):

    default
    ###################
    # ADD THEME FILES #
    ###################
    COPY images/ /tmp/custom_theme/images/
    

5. Install apps

The RUN instruction can be used to run any command during the build. For long commands, the \ (backslash) character can be used to continue a RUN instruction on the next line for easier readability.

For this image we need to run the tethys install command for each of our apps. The trickiest part about doing this in a Docker build is activating the tethys environment, which must be done for each RUN call. Add the following lines to the Dockerfile:

default
###########
# INSTALL #
###########
# Bokeh App
RUN /bin/bash -c "cd ${TETHYS_HOME}/apps/tethysapp-bokeh_tutorial && \
    . ${CONDA_HOME}/bin/activate tethys && \
    tethys install --no-db-sync"
# Dam Inventory
RUN /bin/bash -c "cd ${TETHYS_HOME}/apps/tethysapp-dam_inventory && \
    . ${CONDA_HOME}/bin/activate tethys && \
    tethys install --no-db-sync"
# Earth Engine
RUN /bin/bash -c "cd ${TETHYS_HOME}/apps/tethysapp-earth_engine && \
    . ${CONDA_HOME}/bin/activate tethys && \
    tethys install --no-db-sync"
# PostGIS App
RUN /bin/bash -c "cd ${TETHYS_HOME}/apps/tethysapp-postgis_app && \
    . ${CONDA_HOME}/bin/activate tethys && \
    tethys install --no-db-sync"
# THREDDS Tutorial
RUN /bin/bash -c "cd ${TETHYS_HOME}/apps/tethysapp-thredds_tutorial && \
    . ${CONDA_HOME}/bin/activate tethys && \
    tethys install --no-db-sync"

Note

The --no-db-sync option should be used when running tethys install in a Dockerfiles. This is because there will not be (and should not be) a database for Tethys to sync to during a Docker build. Any database initialization steps need to occur when the container starts (run time), not when the image is built (build time).

Note

Remember that commands are run by sh by default. When running tethys commands in a RUN instruction you should use bash to execute the activate and tethys commands as illustrated above. This pattern is summarized as follows:

default
/bin/bash -c . "${CONDA_HOME}/bin/activate tethys && tethys <command>"

The -c option to the bash command allows you to specify a command to run. Place the command in quotes as shown above. The && operator is used to join commands on one line. If the first command fails, the second will not be executed. Alternatively, you may use ; operator to join commands and all of the commands will be executed regardless of the outcome of the previous commands.

6. Expose ports (optional)

The EXPOSE instruction is used to tell Docker which ports the application running inside the container listens on. In the Tethys Platform Docker image, Tethys Portal has been configured to run on port 80, which is the standard HTTP port. Add the following lines to the Dockerfile to inform Docker of this fact:

default
#########
# PORTS #
#########
EXPOSE 80

Note

This step is optional, because port 80 is already exposed by the Tethys Platform Docker image. However, having it in your Dockerfile is a good reminder.

7. Default command (optional)

The CMD instruction is used to specify the default command that is executed when the container starts. The Tethys Platform Docker image provides a run.sh script that performs the tasks that need to happen when the container starts, including starting the servers that run Tethys Portal.

The WORKDIR instruction is used to specify the working directory for the CMD, RUN, COPY, and ADD instructions. You are welcome to use WORKDIR multiple times throughout the Dockerfile to simplify any custom RUN instructions you may need. However, we recommend setting it to ${TETHYS_HOME} before the CMD instruction, as the base image assumes this is the case.

Add the following lines to the Dockerfile:

default
#######
# RUN #
#######
WORKDIR ${TETHYS_HOME}
CMD bash run.sh

Note

This step is optional, because the CMD instruction is already set by the Tethys Platform Docker image as shown above. However, having it in your Dockerfile is a good reminder of the default behavior. You may also use CMD in your Dockerfile to override the default behavior by providing a custom script or command. If you do so, place your custom script in ${TETHYS_HOME} and be sure to call the run.sh at the end of your custom script to make sure Tethys Platform starts up appropriately. To learn more about the run.sh see: Run.sh.

8. Commit Changes

Add the images to the repository and commit the changes to the Dockerfile:

default
git add .
git commit -m "Initial Dockerfile complete"

Solution

This concludes this portion of the tutorial. You can view the solution on GitHub at https://github.com/tethysplatform/tethys_portal_docker or clone it as follows:

git clone https://github.com/tethysplatform/tethys_portal_docker
cd tethys_portal_docker
git checkout -b dockerfile-solution dockerfile-solution-4.0

What's Next?

Continue to the next tutorial to learn how to perform runtime initialization when the container starts.