快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」
见如下链接:《实战-Cerbot结合阿里云dns插件实现自动续期-20250305(测试成功)(推荐)》

/root/grtblog/nginx/nginx.conf 1worker_processes auto;
2
3events {
4 worker_connections 1024;
5}
6
7http {
8 include /etc/nginx/mime.types;
9 default_type application/octet-stream;
10
11 sendfile on;
12 tcp_nopush on;
13 tcp_nodelay on;
14 keepalive_timeout 65;
15
16 # Docker embedded DNS – re-resolve container IPs every 10s.
17 resolver 127.0.0.11 valid=10s ipv6=off;
18
19 map $http_upgrade $connection_upgrade {
20 default upgrade;
21 '' close;
22 }
23
24 # Preserve real client IP from an upstream reverse proxy when present.
25 map $http_x_real_ip $client_real_ip {
26 default $http_x_real_ip;
27 '' $remote_addr;
28 }
29
30 # 80端口:重定向所有请求到HTTPS
31 server {
32 listen 80;
33 server_name grtblog.onedayxyy.cn;
34 # 强制跳转到HTTPS
35 return 301 https://$host$request_uri;
36 }
37
38 # 443端口:HTTPS配置
39 server {
40 listen 443 ssl http2;
41 server_name grtblog.onedayxyy.cn;
42
43 # SSL证书配置(容器内路径,后续会挂载宿主机证书到这个路径)
44 ssl_certificate /etc/nginx/ssl/fullchain.pem;
45 ssl_certificate_key /etc/nginx/ssl/privkey.pem;
46
47 # SSL优化配置(可选但推荐)
48 ssl_protocols TLSv1.2 TLSv1.3;
49 ssl_prefer_server_ciphers on;
50 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
51 ssl_session_timeout 1d;
52 ssl_session_cache shared:SSL:10m;
53 ssl_session_tickets off;
54 add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
55
56 root /usr/share/nginx/html;
57 index index.html;
58
59 client_max_body_size 200M;
60
61 location = /healthz {
62 access_log off;
63 add_header Content-Type text/plain;
64 return 200 'ok';
65 }
66
67 location /api/v2/ws/ {
68 set $upstream_server http://grtblog-server:8080;
69 proxy_http_version 1.1;
70 proxy_set_header Upgrade $http_upgrade;
71 proxy_set_header Connection $connection_upgrade;
72 proxy_set_header Host $host;
73 proxy_set_header X-Real-IP $client_real_ip;
74 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
75 proxy_set_header X-Forwarded-Proto $scheme;
76 proxy_pass $upstream_server;
77 }
78
79 location = /api/v2/admin/ai/rewrite-content/stream {
80 set $upstream_server http://grtblog-server:8080;
81 proxy_http_version 1.1;
82 proxy_set_header Connection "";
83 proxy_set_header Host $host;
84 proxy_set_header X-Real-IP $client_real_ip;
85 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
86 proxy_set_header X-Forwarded-Proto $scheme;
87 proxy_buffering off;
88 proxy_request_buffering off;
89 proxy_cache off;
90 proxy_read_timeout 3600s;
91 proxy_send_timeout 3600s;
92 add_header X-Accel-Buffering no;
93 proxy_pass $upstream_server;
94 }
95
96 location = /api/v2/admin/ai/generate-summary/stream {
97 set $upstream_server http://grtblog-server:8080;
98 proxy_http_version 1.1;
99 proxy_set_header Connection "";
100 proxy_set_header Host $host;
101 proxy_set_header X-Real-IP $client_real_ip;
102 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
103 proxy_set_header X-Forwarded-Proto $scheme;
104 proxy_buffering off;
105 proxy_request_buffering off;
106 proxy_cache off;
107 proxy_read_timeout 3600s;
108 proxy_send_timeout 3600s;
109 add_header X-Accel-Buffering no;
110 proxy_pass $upstream_server;
111 }
112
113 location /api/ {
114 set $upstream_server http://grtblog-server:8080;
115 proxy_set_header Host $host;
116 proxy_set_header X-Real-IP $client_real_ip;
117 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
118 proxy_set_header X-Forwarded-Proto $scheme;
119 proxy_pass $upstream_server;
120 }
121
122 location /uploads/ {
123 set $upstream_server http://grtblog-server:8080;
124 proxy_set_header Host $host;
125 proxy_set_header X-Real-IP $client_real_ip;
126 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
127 proxy_set_header X-Forwarded-Proto $scheme;
128 proxy_pass $upstream_server;
129 }
130
131 location /health/ {
132 set $upstream_server http://grtblog-server:8080;
133 proxy_set_header Host $host;
134 proxy_set_header X-Real-IP $client_real_ip;
135 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
136 proxy_set_header X-Forwarded-Proto $scheme;
137 proxy_pass $upstream_server;
138 }
139
140 location = /feed {
141 set $upstream_server http://grtblog-server:8080;
142 proxy_set_header Host $host;
143 proxy_set_header X-Real-IP $client_real_ip;
144 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
145 proxy_set_header X-Forwarded-Proto $scheme;
146 rewrite ^ /api/v2/public/feed break;
147 proxy_pass $upstream_server;
148 }
149
150 location = /rss.xml {
151 set $upstream_server http://grtblog-server:8080;
152 proxy_set_header Host $host;
153 proxy_set_header X-Real-IP $client_real_ip;
154 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
155 proxy_set_header X-Forwarded-Proto $scheme;
156 rewrite ^ /api/v2/public/rss.xml break;
157 proxy_pass $upstream_server;
158 }
159
160 # Federation: .well-known (webfinger, nodeinfo, blog-federation)
161 location /.well-known/ {
162 set $upstream_server http://grtblog-server:8080;
163 proxy_set_header Host $host;
164 proxy_set_header X-Real-IP $client_real_ip;
165 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
166 proxy_set_header X-Forwarded-Proto $scheme;
167 proxy_pass $upstream_server;
168 }
169
170 # Federation: ActivityPub (actor, inbox, outbox, etc.)
171 location /ap/ {
172 set $upstream_server http://grtblog-server:8080;
173 proxy_set_header Host $host;
174 proxy_set_header X-Real-IP $client_real_ip;
175 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
176 proxy_set_header X-Forwarded-Proto $scheme;
177 proxy_pass $upstream_server;
178 }
179
180 # Federation: NodeInfo 2.0
181 location /nodeinfo/ {
182 set $upstream_server http://grtblog-server:8080;
183 proxy_set_header Host $host;
184 proxy_set_header X-Real-IP $client_real_ip;
185 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
186 proxy_set_header X-Forwarded-Proto $scheme;
187 proxy_pass $upstream_server;
188 }
189
190 location = /admin {
191 return 301 /admin/;
192 }
193
194 location /admin/ {
195 set $upstream_server http://grtblog-server:8080;
196 proxy_set_header Host $host;
197 proxy_set_header X-Real-IP $client_real_ip;
198 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
199 proxy_set_header X-Forwarded-Proto $scheme;
200 proxy_pass $upstream_server;
201 }
202
203 location / {
204 try_files $uri $uri.html $uri/index.html @frontend_fallback;
205 }
206
207 location @frontend_fallback {
208 set $upstream_renderer http://grtblog-renderer:3000;
209 proxy_set_header Host $host;
210 proxy_set_header X-Real-IP $client_real_ip;
211 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
212 proxy_set_header X-Forwarded-Proto $scheme;
213 proxy_buffer_size 256k;
214 proxy_buffers 8 256k;
215 proxy_busy_buffers_size 512k;
216 proxy_intercept_errors on;
217 error_page 502 503 504 =404 /404.html;
218 proxy_pass $upstream_renderer;
219 }
220
221 location = /404.html {
222 root /usr/share/nginx/html;
223 internal;
224 }
225 }
226}/root/grtblog/nginx/nginx.conf 1name: grtblog
2services:
3 server:
4 image: "${IMAGE_REPO_PREFIX:-}grtblog-server:${APP_VERSION:-local}"
5 build:
6 context: ..
7 dockerfile: deploy/docker/server.Dockerfile
8 args:
9 APP_VERSION: "${APP_VERSION:-local}"
10 BUILD_COMMIT: "${BUILD_COMMIT:-unknown}"
11 VITE_APP_BASE: "${VITE_APP_BASE:-/admin/}"
12 VITE_APP_NAME: "${VITE_APP_NAME:-Grtblog Admin}"
13 VITE_APP_TITLE: "${VITE_APP_TITLE:-管理后台}"
14 VITE_WATERMARK_CONTENT: "${VITE_WATERMARK_CONTENT:-}"
15 VITE_API_BASE_URL: "${VITE_API_BASE_URL:-/api/v2}"
16 container_name: grtblog-server
17 environment:
18 APP_ENV: production
19 APP_PORT: "8080"
20 APP_PROXY_HEADER: "X-Forwarded-For"
21 APP_TRUSTED_PROXY_CHECK: "true"
22 APP_IP_VALIDATION: "true"
23 AUTH_SECRET: "${AUTH_SECRET:?AUTH_SECRET is required}"
24 DB_DRIVER: postgres
25 DB_DSN: "postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-change-me}@postgres:5432/${POSTGRES_DB:-grtblog}?sslmode=disable"
26 REDIS_ADDR: redis:6379
27 REDIS_PASSWORD: "${REDIS_PASSWORD:-}"
28 REDIS_DB: "0"
29 REDIS_PREFIX: "${REDIS_PREFIX:-grtblog:}"
30 HTMLSNAPSHOT_BASE_URL: "http://renderer:3000"
31 APP_UPDATE_CHECK_ENABLED: "${APP_UPDATE_CHECK_ENABLED:-true}"
32 APP_UPDATE_CHECK_REPO: "${APP_UPDATE_CHECK_REPO:-grtsinry43/grtblog-v2}"
33 APP_UPDATE_CHANNEL: "${APP_UPDATE_CHANNEL:-stable}"
34 depends_on:
35 postgres:
36 condition: service_healthy
37 redis:
38 condition: service_healthy
39 renderer:
40 condition: service_started
41 volumes:
42 - ./storage/html:/app/storage/html
43 - ./storage/uploads:/app/storage/uploads
44 - ./storage/geoip:/app/storage/geoip
45 networks:
46 - grtblog-internal
47 restart: unless-stopped
48
49 renderer:
50 image: "${IMAGE_REPO_PREFIX:-}grtblog-renderer:${APP_VERSION:-local}"
51 build:
52 context: ..
53 dockerfile: deploy/docker/web.Dockerfile
54 args:
55 APP_VERSION: "${APP_VERSION:-local}"
56 BUILD_COMMIT: "${BUILD_COMMIT:-unknown}"
57 container_name: grtblog-renderer
58 environment:
59 NODE_ENV: production
60 HOST: 0.0.0.0
61 PORT: "3000"
62 INTERNAL_API_BASE_URL: "http://server:8080/api/v2"
63 volumes:
64 - ./storage/html:/assets
65 networks:
66 - grtblog-internal
67 restart: unless-stopped
68
69 nginx:
70 image: nginx:1.27-alpine
71 container_name: grtblog-nginx
72 ports:
73 - "80:80"
74 - "443:443"
75 volumes:
76 - ./storage/html:/usr/share/nginx/html:ro
77 - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
78 - /etc/letsencrypt/archive/onedayxyy.cn/fullchain1.pem:/etc/nginx/ssl/fullchain.pem:ro # 挂载证书
79 - /etc/letsencrypt/archive/onedayxyy.cn/privkey1.pem:/etc/nginx/ssl/privkey.pem:ro # 挂载私钥
80 depends_on:
81 - server
82 - renderer
83 networks:
84 - grtblog-internal
85 restart: unless-stopped
86
87 postgres:
88 image: postgres:17-alpine
89 container_name: grtblog-postgres
90 environment:
91 POSTGRES_DB: "${POSTGRES_DB:-grtblog}"
92 POSTGRES_USER: "${POSTGRES_USER:-postgres}"
93 POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-change-me}"
94 volumes:
95 - postgres_data:/var/lib/postgresql/data
96 healthcheck:
97 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-grtblog}"]
98 interval: 10s
99 timeout: 5s
100 retries: 10
101 networks:
102 - grtblog-internal
103 restart: unless-stopped
104
105 redis:
106 image: redis:7-alpine
107 container_name: grtblog-redis
108 command: ["redis-server", "--appendonly", "yes"]
109 volumes:
110 - redis_data:/data
111 healthcheck:
112 test: ["CMD", "redis-cli", "ping"]
113 interval: 10s
114 timeout: 3s
115 retries: 10
116 networks:
117 - grtblog-internal
118 restart: unless-stopped
119
120volumes:
121 postgres_data:
122 name: grtblog_postgres_data
123 redis_data:
124 name: grtblog_redis_data
125
126networks:
127 grtblog-internal:
128 name: grtblog-internal
129 driver: bridgehttps://grtblog.onedayxyy.cn/admin/


日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白