Skip to content

Repository files navigation

Confluence + Traefik + Let's Encrypt — Docker Compose

Deployment Verification License: MIT

Contents

This repository deploys Confluence (Data Center) behind Traefik with automatic Let's Encrypt TLS, backed by PostgreSQL, with scheduled backups (database + application data) and companion restore scripts. One docker compose up away from a team wiki at https://your-domain.

📙 Full narrative installation guide on the blog: heyvaldemar.com/install-confluence-using-docker-compose/.

⚖️ Licensing note: Confluence Data Center requires an Atlassian license (trials available). This template handles the infrastructure; the license is between you and Atlassian.

Why this stack?

Need This stack Manual install Kubernetes Other compose examples
Ready to deploy in <15 min ✅ if K8s is already running Often
TLS via Let's Encrypt, auto-renewed ✅ Traefik ACME built-in Manual certbot Via cert-manager Rare
External PostgreSQL wired with healthchecks Manual Varies
Scheduled DB + data backups + pruning Manual cron External Rare
Restore scripts included ✅ two scripts Manual Manual Rare
Upstream images pinned by sha256 digest N/A Depends Rare
Weekly pin-freshness check in CI N/A Depends Rare
CI-verified deployment on every push ✅ /status answers N/A Varies Rare
Credentials via env (never committed) N/A K8s Secrets Often committed plaintext

Four moving parts (Traefik + Confluence + Postgres + backups). No Kubernetes prerequisites, no manual certificate management.

Prerequisites

  • A Linux server with a public IP and RAM for the JVM — defaults are 8 GB min / 12 GB max heap for a production wiki; lower them in .env for small instances.
  • Docker Engine 24+ and Docker Compose 2.20+.
  • A domain you control, with two A records pointing at your server's public IP — one for Confluence, one for the Traefik dashboard. DNS must propagate before deploy.
  • Ports 80 and 443 open on the server's firewall.
  • Disk for attachments, indexes, and backups.

Getting started

# 1. Clone
git clone https://github.com/heyvaldemar/confluence-traefik-letsencrypt-docker-compose
cd confluence-traefik-letsencrypt-docker-compose

# 2. Create the two Docker networks the stack expects
docker network create traefik-network
docker network create confluence-network

# 3. Copy the environment template and fill in required values
cp .env.example .env
$EDITOR .env
# ^ Required: CONFLUENCE_DB_PASSWORD, CONFLUENCE_HOSTNAME, CONFLUENCE_URL,
#   TRAEFIK_HOSTNAME, TRAEFIK_ACME_EMAIL, TRAEFIK_BASIC_AUTH.

# 4. Deploy
docker compose -f confluence-traefik-letsencrypt-docker-compose.yml -p confluence up -d

First boot takes a few minutes. Then https://${CONFLUENCE_HOSTNAME} serves the setup wizard — choose production installation, point it at the bundled database (host postgres, database confluencedb, user confluencedbuser, your CONFLUENCE_DB_PASSWORD), and follow the license step.

What success looks like

# Services healthy:
docker compose -f confluence-traefik-letsencrypt-docker-compose.yml -p confluence ps

# Confluence status endpoint:
curl -fsS "https://${CONFLUENCE_HOSTNAME}/status"
# Expected before setup: {"state":"FIRST_RUN"} — after setup: {"state":"RUNNING"}

# Traefik issued a certificate:
docker compose -p confluence logs traefik | grep -i "adding certificate"

# First backup lands after BACKUP_INIT_SLEEP (default 30m):
docker compose -p confluence logs backups | tail -3

Common first-deploy issues

  • Cert issuance fails. DNS hasn't propagated or port 80 isn't reachable from the internet.
  • docker compose up fails with set in .env. A required variable is empty; the error names it.
  • network confluence-network not found. Step 2 was skipped.
  • OOM-killed container. Lower CONFLUENCE_JVM_MINIMUM_MEMORY/CONFLUENCE_JVM_MAXIMUM_MEMORY in .env to fit your host.

Apply .env or compose-file changes

docker compose -f confluence-traefik-letsencrypt-docker-compose.yml -p confluence up -d --force-recreate

Features

  • Confluence Data Center 10.2 line with an external PostgreSQL 16, healthchecked and backupable.
  • Traefik v3 with automatic HTTP→HTTPS redirect and Let's Encrypt TLS-ALPN certificate issuance.
  • Basic-auth protected Traefik dashboard on a separate hostname.
  • Tunable JVM heap via CONFLUENCE_JVM_MINIMUM_MEMORY / CONFLUENCE_JVM_MAXIMUM_MEMORY.
  • Scheduled backups of the database (pg_dump | gzip) and application data (tar.gz) with retention pruning, plus restore scripts for both.
  • Credentials required at deploy time — compose fails fast if .env is incomplete.

Supply chain trust

This repository is a deployment template, not a custom Docker image. It orchestrates three upstream images:

All three are pinned to tag@sha256:<digest> as interpolation defaults in the compose file's x-images block — git pull alone delivers the version combination this repository has tested; an *_IMAGE_TAG variable in .env overrides the default deliberately.

The weekly check-pin-freshness CI job re-resolves each pinned tag against its registry, compares the pinned Confluence version against the highest release tag on Docker Hub (Atlassian publishes no GitHub releases), and checks the Traefik minor against the latest upstream release. CI runs on every push, pull request, and every Monday at 06:00 UTC. GitHub Actions are pinned by commit SHA; Dependabot keeps those fresh.

Production checklist

  • Strong secrets. CONFLUENCE_DB_PASSWORD at 24+ random characters; regenerate the Traefik dashboard BCrypt hash per deployment.
  • Size the JVM to your instance — the defaults suit a real team wiki; shrink for evaluation.
  • Host-mount the backup volumes for disaster recovery.
  • Verify Let's Encrypt cert issuance in the Traefik logs on first start.
  • Back up before upgrades and follow Atlassian's upgrade guidance — there is no downgrade path.
  • Know the restore procedure. Run both restore scripts against a test environment before you need them.

Backups

The backups container performs a dump → archive → prune → sleep loop: pg_dump | gzip of the Confluence database, tar.gz of the application data (attachments, indexes), pruning by retention windows, then sleeping BACKUP_INTERVAL (default 24h).

Verify backups are running:

docker compose -p confluence logs backups | tail -5

Restore with the interactive scripts (chmod +x *.sh once): ./confluence-restore-database.sh, then ./confluence-restore-application-data.sh.

Testing

The Deployment Verification workflow runs on every push, pull request, and every Monday at 06:00 UTC:

  1. Lint — shellcheck on both restore scripts, actionlint on the workflow.
  2. Trivy scans of all three pinned images (CRITICAL/HIGH, SARIF to the Security tab).
  3. Pin freshness (weekly/manual) — digest drift, Confluence Docker Hub tag lag, Traefik release lag.
  4. Deploy-and-test — boots the full stack with ephemeral credentials and requires /status to answer through Traefik — the shipped configuration must produce a serving Confluence, not just started containers.

A green run is the authoritative proof that the template deploys end-to-end.

Security Notes

  • Credentials are read from .env at deploy time; .env is gitignored and compose fails fast on missing required variables.
  • Pre-rotation advisory. Releases before v1.0.0 (2026-08-31) shipped a tracked .env with a generated-looking database password. Rotate CONFLUENCE_DB_PASSWORD if your deployment reused it.
  • The database listens only on the internal network.
  • Upstream image digests are pinned; the weekly freshness job flags drift loudly.

About the maintainer

Maintained by Vladimir Mikhalev — Docker Captain · IBM Champion · AWS Community Builder

YouTube · Blog · LinkedIn