services: database: image: postgres:16-alpine container_name: codimd-postgres environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=${POSTGRES_DB} # PostgreSQL security settings - POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C volumes: - ./pgdata:/var/lib/postgresql/data restart: always healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 networks: - codimd-network # Security: restrict to internal network only ports: [] # Additional security options security_opt: - no-new-privileges:true read_only: true tmpfs: - /tmp - /var/run/postgresql codimd: image: hackmdio/hackmd:2.6.1 container_name: codimd-app environment: - CMD_DB_URL=${CMD_DB_URL} - CMD_USECDN=false - CMD_SESSION_SECRET=${CMD_SESSION_SECRET} - CMD_SESSION_LIFETIME=1209600000 - CMD_PORT=3000 depends_on: database: condition: service_healthy ports: - "127.0.0.1:3000:3000" volumes: - ./upload-data:/home/hackmd/app/public/uploads restart: always healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/healthz"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - codimd-network security_opt: - no-new-privileges:true networks: codimd-network: driver: bridge internal: false