Este guia mostra como usar as páginas de erro do CodeAtlas em ambientes Docker, cobrindo três abordagens: bind mount com nginx, imagem personalizada e serviço dedicado como backend de erros.
As páginas disponíveis são: 404.html, 500.html, 503.html, 429.html, 401.html e 403.html.
A forma mais rápida de começar. Clone o repositório no servidor e monte o diretório diretamente no container nginx — sem rebuild de imagem.
git clone https://github.com/codeatlasdev/404.git /var/www/error-pagesservices:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /var/www/error-pages:/usr/share/nginx/html/errors:ro
restart: unless-stoppedevents {}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
# Páginas de erro personalizadas
error_page 401 /errors/401.html;
error_page 403 /errors/403.html;
error_page 404 /errors/404.html;
error_page 429 /errors/429.html;
error_page 500 /errors/500.html;
error_page 503 /errors/503.html;
location /errors/ {
internal;
root /usr/share/nginx/html;
}
location / {
try_files $uri $uri/ =404;
}
}
}docker compose up -dPara atualizar as páginas basta fazer git pull em /var/www/error-pages — nenhum rebuild necessário.
Ideal quando você quer distribuir as páginas embutidas na própria imagem, sem depender de volumes no host.
git clone https://github.com/codeatlasdev/404.git
cd 404FROM nginx:alpine
# Remove a página padrão do nginx
RUN rm -rf /usr/share/nginx/html/*
# Copia as páginas de erro
COPY 404.html 500.html 503.html 429.html 401.html 403.html /usr/share/nginx/html/errors/
# Configuração do nginx com as páginas de erro mapeadas
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80events {}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
error_page 401 /errors/401.html;
error_page 403 /errors/403.html;
error_page 404 /errors/404.html;
error_page 429 /errors/429.html;
error_page 500 /errors/500.html;
error_page 503 /errors/503.html;
location /errors/ {
internal;
root /usr/share/nginx/html;
}
location / {
try_files $uri $uri/ =404;
}
}
}# Build da imagem
docker build -t codeatlasdev/error-pages:latest .
# Executar localmente para testar
docker run -d -p 8080:80 --name error-pages codeatlasdev/error-pages:latest
# Verificar a página 404
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/pagina-que-nao-existeservices:
nginx:
image: codeatlasdev/error-pages:latest
container_name: nginx
ports:
- "80:80"
restart: unless-stoppedNesta abordagem, as páginas de erro rodam como um microserviço independente dentro da rede Docker. Proxies como Traefik e HAProxy podem direcionar respostas de erro para esse serviço.
O serviço error-pages fica acessível internamente pela rede Docker no endereço http://error-pages:80. O proxy (Traefik, HAProxy, nginx) é configurado para redirecionar respostas com status 4xx/5xx para esse backend.
services:
error-pages:
image: nginx:alpine
container_name: error-pages
volumes:
- /var/www/error-pages:/usr/share/nginx/html/errors:ro
- ./error-pages.nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- proxy
restart: unless-stopped
# Não expõe porta para o host — acesso apenas pela rede internaevents {}
http {
include /etc/nginx/mime.types;
default_type text/html;
server {
listen 80;
server_name _;
root /usr/share/nginx/html/errors;
# Retorna a página correspondente ao código de status
location = /401 { try_files /401.html =404; }
location = /403 { try_files /403.html =404; }
location = /404 { try_files /404.html =404; }
location = /429 { try_files /429.html =404; }
location = /500 { try_files /500.html =404; }
location = /503 { try_files /503.html =404; }
# Fallback genérico
location / {
return 404;
}
}
}No docker-compose.yml do Traefik, adicione o middleware de erros apontando para o serviço:
services:
traefik:
image: traefik:v3.0
command:
- --providers.docker=true
- --entrypoints.web.address=:80
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- proxy
error-pages:
image: nginx:alpine
volumes:
- /var/www/error-pages:/usr/share/nginx/html/errors:ro
- ./error-pages.nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- proxy
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.error-pages.rule=Host(`error-pages.internal`)"
- "traefik.http.services.error-pages.loadbalancer.server.port=80"
# Middleware que captura erros 4xx e 5xx e os envia para este serviço
- "traefik.http.middlewares.error-handler.errors.status=400-599"
- "traefik.http.middlewares.error-handler.errors.service=error-pages"
- "traefik.http.middlewares.error-handler.errors.query=/{status}"
networks:
proxy:
external: trueAs páginas de erro do CodeAtlas são arquivos HTML estáticos — não há processo em execução para receber variáveis de ambiente. Configurações como URL do suporte ou nome do serviço devem ser ajustadas diretamente nos arquivos HTML antes do build da imagem ou do deploy do volume.
Adicione um health check ao serviço error-pages para que o Docker (e orquestradores como Swarm) monitorem a disponibilidade do container:
services:
error-pages:
image: nginx:alpine
volumes:
- /var/www/error-pages:/usr/share/nginx/html/errors:ro
- ./error-pages.nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- proxy
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:80/404"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10sO health check solicita /404 ao próprio container — se o nginx responder, o serviço está saudável. Você pode verificar o estado com:
docker inspect --format='{{.State.Health.Status}}' error-pagesCombina um serviço nginx principal, uma aplicação de exemplo e o serviço dedicado de páginas de erro. Todos compartilham a mesma rede interna.
services:
# ─── Aplicação principal ───────────────────────────────────────────────────
app:
image: node:20-alpine
container_name: app
working_dir: /app
volumes:
- ./app:/app
command: node server.js
networks:
- internal
restart: unless-stopped
# ─── Proxy nginx (ponto de entrada) ────────────────────────────────────────
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- internal
depends_on:
- app
- error-pages
restart: unless-stopped
# ─── Serviço de páginas de erro ────────────────────────────────────────────
error-pages:
image: nginx:alpine
container_name: error-pages
volumes:
- /var/www/error-pages:/usr/share/nginx/html/errors:ro
- ./error-pages.nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- internal
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:80/404"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
networks:
internal:
driver: bridgeevents {}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Upstream da aplicação
upstream app {
server app:3000;
}
# Upstream do serviço de páginas de erro
upstream error_pages {
server error-pages:80;
}
server {
listen 80;
server_name _;
# Intercepta erros e os encaminha para o serviço dedicado
error_page 401 = @error_401;
error_page 403 = @error_403;
error_page 404 = @error_404;
error_page 429 = @error_429;
error_page 500 502 504 = @error_500;
error_page 503 = @error_503;
location @error_401 {
internal;
proxy_pass http://error_pages/401;
}
location @error_403 {
internal;
proxy_pass http://error_pages/403;
}
location @error_404 {
internal;
proxy_pass http://error_pages/404;
}
location @error_429 {
internal;
proxy_pass http://error_pages/429;
}
location @error_500 {
internal;
proxy_pass http://error_pages/500;
}
location @error_503 {
internal;
proxy_pass http://error_pages/503;
}
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}# Clone as páginas de erro
git clone https://github.com/codeatlasdev/404.git /var/www/error-pages
# Suba a stack
docker compose up -d
# Verifique os containers
docker compose ps
# Acompanhe os logs
docker compose logs -fMais detalhes sobre a integração com proxies específicos estão nos guias de nginx, Traefik e Caddy.