services: joplin: image: ${JOPLIN_IMAGE:-joplin/server:latest} container_name: joplin restart: unless-stopped depends_on: joplin-db: condition: service_healthy environment: - TZ=Asia/Shanghai - APP_PORT=22300 - APP_BASE_URL=https://${JOPLIN_DOMAIN:?请在 .env 中设置 JOPLIN_DOMAIN} - DB_CLIENT=pg - POSTGRES_HOST=joplin-db - POSTGRES_PORT=5432 - POSTGRES_DATABASE=${POSTGRES_DATABASE:-joplin} - POSTGRES_USER=${POSTGRES_USER:-joplin} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?请在 .env 中设置 POSTGRES_PASSWORD} - MAILER_ENABLED=${MAILER_ENABLED:-0} - MAILER_HOST=${MAILER_HOST:-} - MAILER_PORT=${MAILER_PORT:-465} - MAILER_SECURITY=${MAILER_SECURITY:-tls} - MAILER_AUTH_USER=${MAILER_AUTH_USER:-} - MAILER_AUTH_PASSWORD=${MAILER_AUTH_PASSWORD:-} - MAILER_NOREPLY_NAME=${MAILER_NOREPLY_NAME:-Joplin} - MAILER_NOREPLY_EMAIL=${MAILER_NOREPLY_EMAIL:-} - MAX_TIME_DRIFT=0 volumes: - /etc/localtime:/etc/localtime:ro ports: - "127.0.0.1:22300:22300" healthcheck: test: ["CMD", "node", "-e", "const http=require('http');const r=http.get('http://127.0.0.1:22300/api/ping',res=>{process.exit(res.statusCode===200?0:1)});r.on('error',()=>process.exit(1));r.setTimeout(4000,()=>{r.destroy();process.exit(1)})"] interval: 30s timeout: 5s retries: 3 start_period: 20s logging: driver: json-file options: max-size: "10m" max-file: "3" joplin-db: image: ${POSTGRES_IMAGE:-postgres:16-alpine} container_name: joplin-db restart: unless-stopped environment: - TZ=Asia/Shanghai - POSTGRES_DB=${POSTGRES_DATABASE:-joplin} - POSTGRES_USER=${POSTGRES_USER:-joplin} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?请在 .env 中设置 POSTGRES_PASSWORD} volumes: - ${JOPLIN_DB_DIR:-/data/joplin/db}:/var/lib/postgresql/data - /etc/localtime:/etc/localtime:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-joplin}"] interval: 10s timeout: 5s retries: 5 start_period: 10s logging: driver: json-file options: max-size: "10m" max-file: "3"