Handling 503 with custom error page

1. The problem I’m having:

I’m trying to show a custom 503 response maintenance page but whatever I try I cannot make it work. I also had a look at all the other related posts, but none of the solutions helped me.

Any help is appreciated.

Thank you.

2. Error messages and/or full log output:

I don’t get any error messages.

3. Caddy version:

v2.7.0-beta.2 h1:jaS1odoRuDR2W8igaKgVGvVjhTNt8xfoz3YPC4bcenA=

4. How I installed and ran Caddy:

via docker-compose

a. System environment:

Ubuntu 22.04

b. Command:

c. Service/unit/compose file:

caddy:
    image: caddy:2.7-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - ./caddy/maintenance.html:/etc/caddy/maintenance.html
      - ./caddy/data:/data
      - ./caddy/config:/config
    networks:
      - web
      - internal
...

d. My complete Caddy config:

{
  # Global options block. Entirely optional, https is on by default
  # Optional email key for lets encrypt
  email abc@d.com
  # Optional staging lets encrypt for testing. Comment out for production.
  acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

handle_errors {
  @maintenance expression {http.error.status_code} == 503
  rewrite @maintenance maintenance.html
  root * /etc/caddy
  file_server
}

www.example.am {
  redir https://example.am{uri}
}
example.am {
  # Enable maintenance mode
  respond * 503  

  #reverse_proxy webapp_1:3000
}

www.api.example.am {
  redir https://api.example.am{uri}
}
api.example.am {
  reverse_proxy api_1:5000
}

5. Links to relevant resources:

handle_errors is a directive, and as such must go within a site block.

With your current config, Caddy thinks handle_errors is a domain name. You can’t place it at the top-level of the config.

See the docs: Caddyfile Concepts — Caddy Documentation

You need to use the error directive, not respond.

Using error triggers an error. Using respond immediately writes a response to the client with that status.

1 Like

Thanks @francislavoie, putting handle_errors directive inside a site block and using the error directive actually solved the problem.

I’m very new to Caddy and had to migrate urgently from Nginx, so haven’t had much time to go through the docs properly.

Thanks again and have a nice day!

1 Like

@francislavoie I have one last question, I’m sorry to bother you again :slight_smile:

How can I implement this maintenance page on all IP addresses except one specific IP address so that I can still access the site during the maintenance mode?

Use a remote_ip matcher (with the not matcher to negate it) and apply it to your error directive to only emit error if the remote IP does not match the one you specified. See Request matchers (Caddyfile) — Caddy Documentation

1 Like

I really appreciate your help, have a great day!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.