services: nginx: image: nginx:alpine restart: unless-stopped depends_on: - outline volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro networks: - default - dokploy-network outline: image: docker.getoutline.com/outlinewiki/outline:1.6.1 restart: unless-stopped env_file: - .env depends_on: postgres: condition: service_healthy redis: condition: service_healthy volumes: - outline-storage:/var/lib/outline/data postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: outline POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: outline volumes: - postgres-data:/var/lib/postgresql/data command: - "postgres" - "-c" - "shared_buffers=128MB" - "-c" - "max_connections=20" - "-c" - "work_mem=4MB" - "-c" - "maintenance_work_mem=64MB" healthcheck: test: ["CMD-SHELL", "pg_isready -U outline"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine restart: unless-stopped command: > redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru volumes: - redis-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 cron: build: context: . dockerfile: cron/Dockerfile restart: unless-stopped depends_on: - postgres volumes: # NOTE: scripts/ is intentionally NOT bind-mounted — it's baked into # the cron image (see cron/Dockerfile) so DokPloy redeploys can't # orphan it. content/ and .git/ stay mounted because the export job # writes commits the host needs to see. - ./content:/app/content - ./.git:/app/.git - /var/run/docker.sock:/var/run/docker.sock:ro # Absolute path required: DokPloy does NOT expand ~ and would otherwise # create a literal "~" directory under the deployment dir. - /root/.ssh:/root/.ssh:ro # Absolute path so DokPloy's rm-rf of the code dir doesn't wipe backups. - /var/backups/outline:/backups/outline env_file: - .env networks: dokploy-network: external: true volumes: outline-storage: name: code_outline-storage external: true postgres-data: name: code_postgres-data external: true redis-data: name: code_redis-data external: true