Getting Started with Docker Compose

Introduction

I have been toying around with Docker for a few months now ever since I first bought a Raspberry Pi. It has been a great learning experience. Currently, I have over 20 self-hosted applications running in Docker. However, last week my power started to flicker and I began to wonder what would happen if my Raspberry Pi completely died?

My persistent data volumes for the containers are stored on a separate network file share in my NAS so I know they would be safe. What I would lose is all of my various environmental variables, port settings, and other miscellaneous settings that are included in my docker run codes. At the rate I am adding containers to my setup, it would take hours to recreate my environment. Then I discovered Docker Compose. Docker Compose allows me to store my docker environment in a single .yaml file and boot it up on any Docker host.

Basic Example

I presently use the docker run command to spin-up an application. It is simple, I just type the command in my terminal, hit enter, and in a few seconds my application is ready for access. The Gitea application container has a simple docker run code that I will use as an example:

docker run \
-p 3000:3000 \
-p 22:22 \
-v gitea:/data \
--restart always \
kunde21/gitea-arm:latest

I used Composerize to easily convert a standard docker run command to a format that I can place inside my docker-compose.yml file. In order to add this as a service in the file it would look like this:

version: '3.3'
services:
    gitea-arm:
        ports:
            - '3000:3000'
            - '22:22'
        volumes:
            - 'gitea:/data'
        restart: always
        image: 'kunde21/gitea-arm:latest'

As you can see, the above docker-compose.yml file contains the same port mappings, volumes, options, and image as the original docker run command.

Example with Variables

Next is an example of a docker run command for a container that has many environmental variables. It is the MariaDB container that is maintained by LinuxServer.io.

docker run \
  --name=mariadb \
  -e PUID=1000 \
  -e PGID=1000 \
  -e MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD \
  -e TZ=America/New_York \
  -e MYSQL_DATABASE=USER_DB_NAME \
  -e MYSQL_USER=MYSQL_USER  \
  -e MYSQL_PASSWORD=DATABASE_PASSWORD \
  -p 3306:3306 \
  -v path_to_data:/config \
  --restart unless-stopped \
  linuxserver/mariadb

After translating the above run command into a docker-compose.yml it comes out like this:

version: '3.3'
services:
    mariadb:
        container_name: mariadb
        environment:
            - PUID=1000
            - PGID=1000
            - MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD
            - TZ=America/New_York
            - MYSQL_DATABASE=USER_DB_NAME
            - MYSQL_USER=MYSQL_USER
            - MYSQL_PASSWORD=DATABASE_PASSWORD
        ports:
            - '3306:3306'
        volumes:
            - 'path_to_data:/config'
        restart: unless-stopped
        image: linuxserver/mariadb

Bringing it all together

I combined my services into a single docker-compose.yml file as outlined below. This file can be placed on a private GitHub repository or a self-hosted git repository. Keeping the file on GitHub allows me to edit it very easily. GitHub also serves as an offsite backup for the file.

version: '3.3'
services:
    gitea-arm:
        ports:
            - '3000:3000'
            - '22:22'
        volumes:
            - 'gitea:/data'
        restart: always
        image: 'kunde21/gitea-arm:latest'

    mariadb:
        container_name: mariadb
        environment:
            - PUID=1000
            - PGID=1000
            - MYSQL_ROOT_PASSWORD=ROOT_ACCESS_PASSWORD
            - TZ=America/New_York
            - MYSQL_DATABASE=USER_DB_NAME
            - MYSQL_USER=MYSQL_USER
            - MYSQL_PASSWORD=DATABASE_PASSWORD
        ports:
            - '3306:3306'
        volumes:
            - 'path_to_data:/config'
        restart: unless-stopped
        image: linuxserver/mariadb

With a master docker compose file, if I ever have to replace my docker host machine all I will have to do is install docker, upload this file onto the machine and run the docker-compose up command and all my applications will spin-up with their assigned port numbers. This will save so much time when compared to running each individual docker run command for all of my containers.

Be the first to comment

Leave a Reply

Your email address will not be published.


*