This is an optional exercise if you have time available.

# Objectives

Run a sample multi-container application using docker compose.

“docker compose” uses a file to describe multiple containers and how they connect to each other.

NOTE: docker compose is really intended for development use, not production. For example, it can only run all the containers on a single host, and it won’t restart containers if they crash

NOTE: there was an older tool called “docker-compose” with a hyphen. Newer versions of docker come with a plugin called “docker compose” with a space.

# Login as root

ssh into your group’s server, where you installed docker, and switch to the “root” user:

    $ sudo -s
    #

# Check docker compose installation

Check that the docker compose plugin has been installed:

    # docker compose version
    Docker Compose version v2.39.1

# Download docker compose files

The application we’re going to deploy is called “Netbox” - a tool for documenting your data center.

The first thing to do is to download the files needed:

    # cd /root
    # git clone https://github.com/netbox-community/netbox-docker.git
    # cd netbox-docker
    # cat docker-compose.yml

`cat docker-compose.yml` displays the contents of that file to the screen. Have a quick look at it: this is quite a complicated one, more than a screenful! It describes six containers: netbox, netbox-worker, netbox-housekeeping, postgres, redis and redis-cache. It also defines some data volumes for persistent storage.

If you look carefully, you can see it references some other files: `env/netbox.env`, `env/postgres.env`, `env/redis.env` which you can also inspect:

    # cat env/netbox.env

    # cat env/postgres.env

    # cat env/redis.env

These contain environment file settings, like you’ve passed with `-e` before - such as passwords for the services to be able to communicate with each other.

There’s one thing missing at the moment, which is the port number for Netbox to listen on. The Netbox authors don’t know which ports are free on your system, so they have left it to you to choose one. Let’s choose port 8000.

You need to create a file `docker-compose.override.yml` to do this, and fortunately they’ve already provided one that you can copy.

Check you’re still in the `/root/netbox-docker` directory:

    # pwd
    /root/netbox-docker

Run this command to copy the example file to the correct name:

    # cp docker-compose.override.yml.example docker-compose.override.yml

Have a look at the contents of this file:

    # cat docker-compose.override.yml

Towards the top you should see:

    services:
      netbox:
        ports:
          - 8000:8080

This accepts incoming connections on host port 8000 and forwards them to the container, which is listening on port 8080. If you wanted to listen on a different port, then you’d change it here.

# Run the containers

Still in the `/root/netbox-docker` directory, type:

    # docker compose up

This reads the file `docker-compose.yml` in the current directory, and creates the containers described in it.

You should see it pulling down all the required container images (which are in multiple layers, downloaded separately), and then starting them. This will take several minutes.

If you see the following error you can ignore it:

    netbox-housekeeping_1  | psycopg2.errors.UndefinedTable: relation "django_session" does not exist
    netbox-housekeeping_1  | LINE 1: DELETE FROM "django_session" WHERE "django_session"."expire_...
    netbox-housekeeping_1  |                     ^

(The “netbox-housekeeping” container does periodic database cleanups, but here it has run before the database has even been created!)

and you can ignore this error

    dependency failed to start: container netbox-docker-netbox-1 is unhealthy

When you are returned to the command line, you can check the running processes:

    # docker compose ps
    NAME                          IMAGE                                         COMMAND                  SERVICE       CREATED         STATUS                     PORTS
    netbox-docker-netbox-1        docker.io/netboxcommunity/netbox:v4.3-3.3.0   "/usr/bin/tini -- /o…"   netbox        5 minutes ago   Up 5 minutes (unhealthy)   0.0.0.0:8000->8080/tcp, [::]:8000->8080/tcp
    netbox-docker-postgres-1      docker.io/postgres:17-alpine                  "docker-entrypoint.s…"   postgres      5 minutes ago   Up 5 minutes (healthy)     5432/tcp
    netbox-docker-redis-1         docker.io/valkey/valkey:8.1-alpine            "docker-entrypoint.s…"   redis         5 minutes ago   Up 5 minutes (healthy)     6379/tcp
    netbox-docker-redis-cache-1   docker.io/valkey/valkey:8.1-alpine            "docker-entrypoint.s…"   redis-cache   5 minutes ago   Up 5 minutes (healthy)     6379/tcp

In order to get to the web interface, you can now:

- Create a security group “groupXY-netbox” which allows TCP port 8000 from the classroom IP address
- Apply this security group to your instance
- Find your instance’s public IP address
- Point your web browser at http://x.x.x.x:8000

(this is http not https this time), and you should have access to the Netbox application. If you want to login, the username and password are “admin” and “admin”. (However you may find that these don’t work, in which case you’d need to create a new admin user; this is now an application-level problem which we are not going to fix here).

When you’ve finished, go back to the console where docker compose was started. Check you are in the correct directory:

    # pwd
    /root/netbox-docker

To stop and delete all the containers, run:

    # docker compose down