Ghost 博客

docker-compose.yml

services:
  ghost:
    container_name: ghost
    restart: unless-stopped
    image: ghost:alpine3.23 # ghost:6.10-alpine # 4.24.0 4.5.0 5.30.0 6.10-alpine
    networks:
      - ghost_net
    volumes:
      - /www/ghost/data/config.production.json:/var/lib/ghost/config.production.json
      - /www/ghost/data/content:/var/lib/ghost/content
      # 建议检查下面的路径映射,通常只需要 content 即可
      - /www/ghost/data/currentcontent:/var/lib/ghost/current/content
    # --- 极致优化配置 ---
    deploy:
      resources:
        limits:
          memory: 192M    # 强制上限 192M,Ghost 足够运行但不会无限制膨胀
          cpus: '0.3'     # 限制仅使用 30% 的 CPU 频率,防止重启时系统假死
    environment:
      # 强制 Node.js 在内存达到 150MB 时进行垃圾回收
      - NODE_OPTIONS=--max-old-space-size=150

networks:
  ghost_net:
    external: true

nginx.conf

# redirect all http traffic to https
server {
    listen 80;
    server_name ghost.atibm.com atibm.com www.atibm.com;
    # google adsense ads.txt
    location /ads.txt {
        alias /usr/share/nginx/html/ghost/ads.txt;
    }
    location /robots.txt {
        alias /usr/share/nginx/html/ghost/robots.txt;
    }
    return 301 https://$host$request_uri;
}
# redirect some domain https traffic to https://ghost.atibm.com
server {
    listen 443 ssl;
    server_name atibm.com www.atibm.com;
    ssl_certificate /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ghost.atibm.com/privkey.pem;
    location /ads.txt {
        alias /usr/share/nginx/html/ghost/ads.txt;
    }
    location /robots.txt {
        alias /usr/share/nginx/html/ghost/robots.txt;
    }
    return 301 https://ghost.atibm.com$request_uri;
}
# defined ghost.atibm.com 443
server {
    listen 443 ssl;
    server_name ghost.atibm.com;
    ssl_certificate     /etc/letsencrypt/live/ghost.atibm.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ghost.atibm.com/privkey.pem;
    root /var/lib/ghost/current/core/server/public;
    access_log /var/log/nginx/ghost-access.log main;
    error_log /var/log/nginx/ghost-error.log warn;
    location /ads.txt {
        alias /usr/share/nginx/html/ghost/ads.txt;
    }
    location /robots.txt {
        alias /usr/share/nginx/html/ghost/robots.txt;
    }
    location / {
        proxy_pass         http://ghost:2368;
        proxy_set_header     Host $host;
        proxy_set_header     X-Real-IP $remote_addr;
        proxy_set_header    X-Forwarded-Proto https;
        proxy_set_header     X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout     150;
        proxy_send_timeout     100;
        proxy_read_timeout    100;
        proxy_buffers        4 32k;
        client_max_body_size    10m;
        client_body_buffer_size    128;
    }
}

config.production.json

{
  "url": "https://ghost.atibm.com/",
  "server": {
    "port": 2368,
    "host": "0.0.0.0"
  },
  "database": {
    "client": "sqlite3",
    "connection": {
      "filename": "/var/lib/ghost/content/data/ghost.db"
    }
  },

  "logging": {
    "transports": ["stdout"]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/lib/ghost/content"
  }
}