diff --git a/config/nginx/error_pages/404.html b/config/nginx/error_pages/404.html
new file mode 100644
index 0000000..7a835ec
--- /dev/null
+++ b/config/nginx/error_pages/404.html
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+ RhodeCode backend server is unreachable
+
+
+
+check service health status:
+
+ ./rccontrol status
+
+make sure rhodecode stack is running with:
+
+ ./rccontrol stack rhodecode up --detach
+
+
+
Possible Causes
+
+ - The RhodeCode server is starting right now.
+ - The RhodeCode server is being restarted.
+ - RhodeCode Stack is not running.
+ - RhodeCode Stack services are unhealthy.
+ - Reload page
+
+
+
+
+
+
diff --git a/config/nginx/nginx_errors.conf b/config/nginx/nginx_errors.conf
new file mode 100644
index 0000000..fbacbea
--- /dev/null
+++ b/config/nginx/nginx_errors.conf
@@ -0,0 +1,69 @@
+user root;
+worker_processes 1;
+
+pid /var/run/nginx.pid;
+error_log /dev/stdout info;
+
+events {
+ worker_connections 256;
+ # multi_accept on;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+ server_tokens off;
+
+ log_format main '$remote_addr - $remote_user [$time_local] '
+ '"$request" $status $body_bytes_sent '
+ '"$http_referer" "$http_user_agent" '
+ '$request_time $upstream_response_time $pipe';
+
+ access_log /dev/stdout main;
+
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+
+ ## custom log format
+ log_format http_log_custom '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $pipe';
+
+ log_format json_log_custom escape=json
+ '{'
+ '"source":"nginx",'
+ '"remote_user":"$remote_user",'
+ '"time_local":"$time_local",'
+ '"remote_addr":"$remote_addr",'
+ '"host":"$host",'
+ '"proxy_x_forwarded_for":"$proxy_add_x_forwarded_for",'
+ '"request":"$request",'
+ '"status": "$status",'
+ '"request_method": "$request_method",'
+ '"body_bytes_sent":"$body_bytes_sent",'
+ '"request_time":"$request_time",'
+ '"upstream_response_time":"$upstream_response_time",'
+ '"http_referrer":"$http_referer",'
+ '"http_scheme":"$scheme",'
+ '"http_user_agent":"$http_user_agent"'
+ '}';
+
+
+ server {
+ listen 80 default;
+ # ensure we get the proper Docker DNS resolver for load balancing.
+ resolver 127.0.0.11 ipv6=off valid=10s;
+ server_name localhost 127.0.0.1;
+ access_log /dev/stdout json_log_custom;
+ error_log /dev/stdout;
+
+ error_page 404 /404.html;
+
+ location / {
+ root /etc/nginx/error_pages;
+ internal;
+ }
+
+ }
+
+}
+
+
diff --git a/docker-compose-services.yaml b/docker-compose-services.yaml
index 38f7b50..7eb01c9 100644
--- a/docker-compose-services.yaml
+++ b/docker-compose-services.yaml
@@ -100,7 +100,6 @@ services:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./config/nginx/http.conf:/etc/nginx/http.conf:ro
- ./config/nginx/proxy.conf:/etc/nginx/proxy.conf:ro
-
- rc_datavolume:/var/opt/rhodecode_data
logging:
@@ -111,9 +110,50 @@ services:
- "traefik.http.routers.nginx.entrypoints=http"
- "traefik.http.routers.nginx.priority=40"
- "traefik.http.routers.nginx.rule=Host(`${RC_HOSTNAME:?must-specify-rhodecode-hostname}`) && PathPrefix(`/_static/rhodecode`)"
- - "traefik.http.services.nginx.loadbalancer.server.port=80"
+ - "traefik.http.routers.nginx.service=nginx-serv"
+ - "traefik.http.services.nginx-serv.loadbalancer.server.port=80"
+
+ # HTTP + SSL example, should be put into .custom/docker-compose-services.override.yaml
+ #- "traefik.http.routers.error-router.entrypoints=http, https"
+
+ nginx-errors:
+ networks:
+ - rhodecode_network
+ image: library/nginx:1.23.3
+
+ restart: always
+
+ environment:
+ NGINX_ENTRYPOINT_QUIET_LOGS: 1
+
+ env_file:
+ - ${RC_ENV_FILE:?must-specify-rc-env-file}
+
+ volumes:
+ - ./config/nginx/nginx_errors.conf:/etc/nginx/nginx.conf:ro
+ - ./config/nginx/error_pages:/etc/nginx/error_pages
+
+ - rc_datavolume:/var/opt/rhodecode_data
+
+ labels:
+ - "traefik.enable=true"
+
+ # error-middleware
+ - "traefik.http.middlewares.error-pages-middleware.errors.status=404"
+ - "traefik.http.middlewares.error-pages-middleware.errors.service=error-pages-service"
+ - "traefik.http.middlewares.error-pages-middleware.errors.query=/{status}.html"
+
+ # error handling router
+ - "traefik.http.routers.error-router.entrypoints=http"
+ - "traefik.http.routers.error-router.priority=5"
+ - "traefik.http.routers.error-router.rule=HostRegexp(`{host:.+}`)"
+ - "traefik.http.routers.error-router.service=error-pages-service"
+ - "traefik.http.routers.error-router.middlewares=error-pages-middleware"
+
+ - "traefik.http.services.error-pages-service.loadbalancer.server.port=80"
+
# HTTP + SSL example, should be put into .custom/docker-compose-services.override.yaml
- #- "traefik.http.routers.nginx.entrypoints=http,https"
+ #- "traefik.http.routers.error-router.entrypoints=http, https"
elasticsearch:
networks: