diff --git a/.gitea/workflows/deploy-main.yml b/.gitea/workflows/deploy-main.yml index 8da1968..af1ea6c 100644 --- a/.gitea/workflows/deploy-main.yml +++ b/.gitea/workflows/deploy-main.yml @@ -25,6 +25,7 @@ jobs: cp docker-compose.yml "$DEPLOY_DIR/docker-compose.yml" cp nginx.conf "$DEPLOY_DIR/nginx.conf" cp upstreams.map "$DEPLOY_DIR/upstreams.map" + cp proxy_to_app.conf "$DEPLOY_DIR/proxy_to_app.conf" cp html/index.html "$DEPLOY_DIR/html/index.html" rm -f "$DEPLOY_DIR/html/preview.html" diff --git a/README.md b/README.md index 4b24623..81f171c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # error-page -`*.takits.me`가 컨테이너 다운으로 502/503/504가 날 때, DSM 기본 에러창 대신 쓰는 공통 nginx. +`*.takits.me`가 컨테이너 다운(502/503/504)이거나 앱이 404/500을 줄 때, DSM 기본 에러창 대신 쓰는 공통 nginx. DSM 리버스 프록시가 **앱 포트에 직접** 붙으면, 그 포트가 닫혀 있을 때 나스가 에러 페이지를 그립니다. 이 컨테이너는 항상 `127.0.0.1:4098`에서 떠 있고, `Host`로 실제 앱에 넘긴 뒤 업스트림이 죽었을 때만 공통 페이지를 보여 줍니다. @@ -9,7 +9,7 @@ DSM 리버스 프록시가 **앱 포트에 직접** 붙으면, 그 포트가 닫 └─ Host가 takits.me 이면 127.0.0.1:4889 ``` -앱의 404/500은 가로채지 않습니다. +페이지 404/500과 게이트웨이 502/503/504는 공통 화면을 씁니다. `/api/` 404만 JSON 그대로 둡니다. ## 배포 @@ -57,5 +57,6 @@ docker exec error-page nginx -s reload | 파일 | 역할 | |------|------| | `upstreams.map` | 호스트별 앱 포트 | -| `html/index.html` | 502/503/504 페이지 | +| `html/index.html` | 404/500/502/503/504 페이지 | +| `proxy_to_app.conf` | 앱으로 넘기는 프록시 설정 | | `nginx.conf` | 프록시 + 에러 가로채기 | diff --git a/docker-compose.yml b/docker-compose.yml index f9bafa3..6417dc5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,7 @@ services: volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./upstreams.map:/etc/nginx/upstreams.map:ro + - ./proxy_to_app.conf:/etc/nginx/proxy_to_app.conf:ro - ./html:/usr/share/nginx/html:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://127.0.0.1:4098/healthz"] diff --git a/html/index.html b/html/index.html index 1bcdf4b..99f8658 100644 --- a/html/index.html +++ b/html/index.html @@ -105,10 +105,7 @@

__STATUS__

__ERROR_TITLE__

-

- We're working to resolve the issue.
- Please try again shortly. -

+

__ERROR_MESSAGE__

diff --git a/nginx.conf b/nginx.conf index 1d44822..368a1de 100644 --- a/nginx.conf +++ b/nginx.conf @@ -20,11 +20,18 @@ http { map $status $error_title { default "Service Unavailable"; + 404 "Not Found"; + 500 "Internal Server Error"; 502 "Bad Gateway"; 503 "Service Unavailable"; 504 "Gateway Timeout"; } + map $status $error_message { + default "We're working to resolve the issue.
Please try again shortly."; + 404 "The page you're looking for could not be found."; + } + include /etc/nginx/upstreams.map; server { @@ -40,7 +47,7 @@ http { return 200 "ok\n"; } - error_page 502 503 504 /__error/index.html; + error_page 404 500 502 503 504 /__error/index.html; location = /__error/index.html { internal; @@ -48,31 +55,20 @@ http { sub_filter_types text/html; sub_filter "__STATUS__" $status; sub_filter "__ERROR_TITLE__" $error_title; + sub_filter "__ERROR_MESSAGE__" $error_message; sub_filter "__HOST__" $host; add_header Cache-Control "no-store" always; add_header X-Content-Type-Options "nosniff" always; } + # API 404 stays with the app so JSON clients keep working. + location /api/ { + error_page 500 502 503 504 /__error/index.html; + include /etc/nginx/proxy_to_app.conf; + } + location / { - if ($app_port = 0) { - return 502; - } - - proxy_pass http://127.0.0.1:$app_port; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - - proxy_connect_timeout 3s; - proxy_send_timeout 3600s; - proxy_read_timeout 3600s; - - # Only replace DSM-style "upstream down" pages. App 404/500 stay as-is. - proxy_intercept_errors on; + include /etc/nginx/proxy_to_app.conf; } } } diff --git a/proxy_to_app.conf b/proxy_to_app.conf new file mode 100644 index 0000000..78253e7 --- /dev/null +++ b/proxy_to_app.conf @@ -0,0 +1,18 @@ +if ($app_port = 0) { + return 502; +} + +proxy_pass http://127.0.0.1:$app_port; +proxy_http_version 1.1; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header Connection $connection_upgrade; + +proxy_connect_timeout 3s; +proxy_send_timeout 3600s; +proxy_read_timeout 3600s; + +proxy_intercept_errors on;