Deployment with Docker Compose¶
tldr;¶
Install docker and docker compose (v2) using your distribution’s packages.
Login to CheckSec container registry with
docker login containers.checksec.com. Get your credentials via support@checksec.comCopy this
docker-compose.ymlover to host, to let’s say/srv/canopy/.Copy Canopy
licensefile to the same directory.Run
docker compose up -d.Check logs with
docker compose logs -fortail -F logs/current.
Warning
Docker will expose ports 80/443 publicly on the server and your host firewall
will not block them! This is how docker works. Do your firewalling outside
the host.
You can change the docker-compose.yml file to bind to a specific IP in
required, see https://docs.docker.com/reference/compose-file/services/#ports
Notes¶
Get your containers.checksec.com registry account via support@checksec.com
Only x86_64 architecture is supported at this stage.
podman is also supported using the docker-compose provider.
TLS Certificate¶
After the first startup of the containers you will have a certs directory. Place
your .pem file in there. It should contain the full certificate chain as well
as the private key (without a password).
The filename doesn’t matter and you can place multiple certificates, for different hostnames.
Self-signed certificates will be generated on-demand for any non-matching hostname.
Restart the canopy container after changing certificates via docker compose restart canopy
Backups¶
All commands below assume Canopy is installed in /srv/canopy/ and are run as
root user from that directory.
Creating a backup¶
This approach uses pg_dump through the running PostgreSQL container, so the
application can remain online.
Dump the database:
docker compose exec postgres pg_dump -U canopy -Fc canopy > canopy_db.sqlc
Archive the application data and configuration:
tar -zcf canopy_files.tgz config/ data/ certs/ license docker-compose.yml
Store both
canopy_db.sqlcandcanopy_files.tgzin your backup location.
Restoring a backup¶
Stop the containers:
docker compose down
Extract the file archive:
tar -zxf canopy_files.tgz
Start only the database container:
docker compose up -d postgres
Restore the database dump:
docker compose exec -T postgres pg_restore -U canopy -d canopy --clean --if-exists --no-owner --no-privileges < canopy_db.sqlc
Start the remaining containers:
docker compose up -d
Migration¶
The instructions in Backups and recovery still hold but the exact commands will differ slightly to compensate for the use of docker.
Exporting a database dump¶
To create a backup of the Canopy database from the Docker PostgreSQL container:
docker compose exec -T postgres pg_dump -U canopy -F c canopy > canopy_db.sqlc
Importing a database dump¶
To restore a database dump into the Docker PostgreSQL container:
Stop the Canopy application container first:
docker compose stop canopy
Restore the dump:
docker compose exec -T postgres pg_restore -U canopy -c -C -d postgres --if-exists < canopy_db.sqlc
Warning
This will wipe the existing database before restoring the backup.
If you need a completely clean slate (e.g., importing from a different environment), drop the database first and let
pg_restorerecreate it:docker compose exec postgres dropdb -U canopy canopy docker compose exec -T postgres pg_restore -U canopy -C -d postgres < canopy_db.sqlc
Warning
Check the output of
pg_restorefor errors. A few warnings about thepublicschema are normal, but other errors could indicate an incomplete import that will cause issues at runtime.Note
If the restore produces errors about roles or permissions, add
-O --no-privilegesto thepg_restorecommand. This skips ownership assignments and privilege statements, which is common when importing a dump from a different environment.Start the Canopy container again:
docker compose start canopy
Configuration data¶
Canopy’s configuration is stored in the ./config directory on the host, which is
mounted into the container as /etc/canopy/.
To restore configuration data from a backup:
tar -xvf canopy_configs.tgz -C ./config --strip-components=2
Review canopy.ini after restoring to ensure any new configuration settings from
the current version are preserved.
File data¶
Canopy stores all uploads, templates, and other files in the ./data directory on
the host, which is mounted into the container as /var/opt/checksec/canopy/.
To restore file data from a backup:
tar -xvf canopy_data.tgz -C ./data --strip-components=4
Note
The --strip-components value depends on how the backup archive was created.
Verify the archive structure with tar -tf before extracting.
Upgrades¶
Run
docker compose pullto pull new versions of the container images.Run
docker compose up -dto recreate containers with updated images.
This will not lead to data loss as all data is stored on the host via mounts.
By default the docker-compose.yml uses the stable tag, which lags behind
releases slightly but receives weekly rebuilds with updated dependencies.
Directories¶
./configwill contain the Canopy config filecanopy.ini../datacontains all user data (uploaded/generated files) as well as plugins, etc../postgresql-datacontains the Postgresql RDBMS’s data../certsfor your TLS certificates../logsfile based logs for canopy container.
These directories are created automatically and prepopulated with default configurations on the first startup. This is expected behaviour even when migrating from an existing non-Docker installation — you can safely replace the generated defaults with your own data afterwards.
At each startup, permissions are corrected to match the requirements of the containers.
Data directory mapping¶
The ./data directory on the host is mounted to /var/opt/checksec/canopy/
inside the canopy container. This directory contains several subdirectories:
data/— user uploads, generated files, report templates, etc.plugins/— installed pluginsbackups/— application backups
Because the host directory is called data and the container has a data
subdirectory inside the mount, host paths will contain data/data/. For
example, the default report template at
/var/opt/checksec/canopy/data/templatedocuments/report/report_xlsx_export_template.xlsx
inside the container maps to
./data/data/templatedocuments/report/report_xlsx_export_template.xlsx on the
host.
Logging¶
By default all containers log to stdout/stderr and Docker will capture these.
They are viewable via docker compose logs -f or similar command.
Additionally the Canopy container will persist logs to the ./logs directory
as docker doesn’t persist logs by default.
Docker can be configured to persist logs by setting "log-driver": "journald"
in /etc/docker/daemon.json.
e.g. echo '{"log-driver": "journald"}' > /etc/docker/daemon.json
See https://docs.docker.com/engine/logging/drivers/journald/
This requires a docker daemon restart as well as container recreation.
Troubleshooting¶
Start off with checking if the containers are running via docker compose ps -a.
All but the init container should be running.
Next check the logs, if the issue seems application based then look at the canopy
container’s logs via docker compose logs canopy.
To create a log file for uploading to our support portal, use:
docker compose logs | gzip > containers.log.gz