Maintaining your Docker Compose host
A Tines deployment on Docker Compose uses more disk space over time. Each upgrade leaves the images from the previous version on the host, containers write logs continuously, and the build cache grows. When the host runs out of space, Tines stops processing events and PostgreSQL refuses writes.
This page covers what uses disk space, how to reclaim it safely, and which commands delete your data.
What uses disk space
Named volumes
The Docker Compose topology we supply defines five named volumes. Docker prefixes each one with the Compose project name, which is usually the directory you run Tines from, so db-data appears as tines_db-data.
Deleting db-data or db-pg18-data destroys your Tines database. Deleting redis-data loses queued work and valid user sessions. Deleting python-packages or npm-packages breaks script actions until you republish those packages.
Data you can reclaim
Images from previous versions usually take the most space. Every upgrade pulls new tines-app, tines-nginx, and tines-command-runner images and leaves the previous ones on the host.
Container logs grow continuously. The tines-app and tines-sidekiq services produce the most.
Build cache accumulates only when you build images on the host, such as custom runtimes.
Checking disk usage
Check free space on the host:
df -hCheck how much of that Docker uses:
docker system dfThe RECLAIMABLE column shows how much you can recover. For a breakdown by image, container, and volume:
docker system df -vContainer logs do not appear in docker system df. To find large log files:
docker ps -a --format '{{.Names}}' | while read -r c; do
log=$(docker inspect --format '{{.LogPath}}' "$c" 2>/dev/null)
[ -n "$log" ] && printf '%-40s %s\n' "$c" "$(sudo du -h "$log" 2>/dev/null | cut -f1)"
done | sort -k2 -hReading log files requires root, so this command uses sudo.
Taking a backup
See data backup recommendations for a full backup strategy. We recommend that you take one of the following before you reclaim space.
Dump the database with pg_dump
Confirm the database name first. It is the DATABASE_NAME in your .env file, and is typically tines_production:
docker compose exec -T db sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -l'Then dump it:
docker compose exec -T db sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -U "$POSTGRES_USER" -d tines_production' \
| gzip > tines-$(date +%F).sql.gzUse db-pg18 in place of db after you migrate to PostgreSQL 18.
Use pg_dump rather than pg_dumpall. pg_dumpall reads pg_authid and fails unless the database user is a superuser, and Tines supports a non-superuser PostgreSQL user.
Copy the volume
Tines must be stopped while you copy the volume:
docker compose stop
docker run --rm -v tines_db-data:/data:ro -v "$PWD":/backup alpine \
tar czf /backup/db-data-$(date +%F).tar.gz -C /data .
docker compose startReplace tines_db-data with the volume name from docker volume ls, and use tines_db-pg18-data after you migrate to PostgreSQL 18. A container running as root writes the archive, so root owns it. Use sudo to read or move it.
On an air-gapped host, use an image you already hold, such as your PostgreSQL image, in place of alpine. Any image that provides tar works.
Use docker compose stop rather than docker compose down. Both stop Tines, but down also removes the containers, which makes your volumes eligible for deletion by the prune commands below. To stop the services gracefully, follow the scale-down order in infrastructure maintenance, which drains the tines-sidekiq queue before it stops the data services.
Reclaiming space
Run these commands while Tines is running. None of them affect volumes.
Remove images from previous versions
docker image prune -aThis removes every image that no container references. After an upgrade, that means the images from your previous Tines version. The images the stack currently uses stay, because its containers reference them.
Run this while Tines is running. After docker compose down, no containers exist to reference the current images, so Docker removes those as well and the next docker compose up pulls them again. On an air-gapped host that pull fails.
Remove build cache
docker builder pruneTines images are pulled rather than built, so this is usually safe. If you build custom runtimes on this host, the next build takes longer.
Remove stopped containers
docker container pruneThis removes containers that have exited. It does not affect the containers in a running stack.
Remove the PostgreSQL 14 volume after migrating
The migration to PostgreSQL 18 leaves the PostgreSQL 14 volume in place so that you can roll back. We recommend that you keep it for at least 24 hours after the migration. Once you have confirmed that Tines works on PostgreSQL 18, remove it with the docker volume rm command the migration script prints when it finishes. See upgrading from PostgreSQL 14 to PostgreSQL 18.
This usually recovers the most space, because the volume holds a complete copy of your database.
Commands that delete your data
The following commands delete named volumes. We recommend that you do not run them on a Tines host unless you have a current backup and intend to destroy data.
docker compose down --volumesThis removes every named volume declared in your Compose file, including both database volumes. It does not ask for confirmation.
docker volume prune --allThis removes all unused volumes, including named ones. A volume counts as unused when no container references it. docker compose down removes the containers, so after it runs every Tines volume qualifies.
docker volume rm <volume>This removes a named volume directly.
Commands that do not delete named volumes
From Docker 23.0, docker volume prune without --all removes only anonymous volumes. Your named Tines volumes remain, even when the stack is stopped. docker system prune --volumes also removes only anonymous volumes.
Docker versions before 23.0 removed named volumes with docker volume prune. Check which version you run:
docker version --format '{{.Server.Version}}'The --all and --volumes flags are what change this behavior.
Reducing future disk usage
Rotate container logs
The docker-compose.yml we supply applies a log rotation policy to every service:
x-default-logging: &default-logging
driver: json-file
options:
max-size: "100m"
max-file: "10"
compress: "true"This limits each service to about 1 GB before compression. A full stack still uses several gigabytes, so include that in your disk sizing.
If you deployed Tines before we added this policy, your services may have no limit and a log file can grow until the host fills. We recommend that you either add the policy to each service in your docker-compose.yml, or set a default for the host in /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "10"
}
}Restart Docker after you edit daemon.json. The policy applies only to containers created afterwards, so recreate the stack to apply it:
docker compose up -d --force-recreateIf you ship logs off the host, or rotate them at the host level, set the driver to journald and remove the json-file options.
Remove old images after every upgrade
We recommend that you run docker image prune -a at the end of each upgrade, once Tines is running and you have confirmed that the new version works. This stops images from previous versions accumulating on the host.
Monitor free disk space
We recommend that you alert on the Tines host at 75% disk usage, so that you have time to act before it fills.