Guides

Maintenance mode

Show visitors a "down for maintenance" page on every domain of a project, instantly and without a redeploy, while the app keeps running behind it.

Sometimes you need visitors to stay away for a while: a database migration, a data import, a big upgrade. Maintenance mode puts a notice in front of the app. While it's on, the edge answers every domain of the project with a maintenance page instead of passing requests to the app.

It takes effect in seconds, needs no redeploy, and doesn't stop anything: the app, its services and its database keep running behind the page, so you can keep working on them.

What you need first

  • A project on one of your own servers. The page is served by the server's edge proxy, so it covers the project's domains on that server.
  • Permission to change the project's settings.

Turn it on

Open Maintenance

Open the project and choose Maintenance in the project menu. You see the Maintenance mode card.

Optionally write a message

Type a short note in Message, for example We're upgrading the database. Back by 18:00 UTC. It is plain text (up to 1,000 characters) shown on the built-in page. Press Save page to keep it.

Switch it on

Turn on the Maintenance mode switch. The toast says Maintenance mode is on, and the hint under the switch reads On: visitors see the maintenance page. That's it: open one of the project's domains and you see the page.

To end maintenance, switch it off. The toast says Maintenance mode is off and the app is served normally again, straight away.

What visitors get

  • The built-in page, titled Down for maintenance, with your message under it.
  • HTTP status 503 Service Unavailable with Retry-After: 300. Browsers, search engines and uptime monitors read that as "temporarily unavailable, come back later", so your search ranking isn't affected by a short window.
  • Cache-Control: no-store, so nobody keeps a cached copy of the notice after you switch it off.
  • Every path gets the page, including API calls, path routes such as /api/ and asset URLs, on every domain of the project. A domain set up only to redirect to another one keeps redirecting, and a project that has never been deployed keeps showing its "not deployed yet" placeholder instead.

Use your own page

Press Use a custom HTML page instead and paste a complete HTML document into Custom HTML (up to 32 KB). Press Save page. While it's filled in, Synq serves your page instead of the built-in one, with the same 503 status. Leave it empty to go back to the built-in page.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Back soon</title>
    <style>body{font-family:system-ui;text-align:center;padding:4rem}</style>
  </head>
  <body>
    <h1>We'll be right back</h1>
    <p>Scheduled maintenance until 18:00 UTC. Follow status.example.com for updates.</p>
  </body>
</html>

Keep the page self-contained: inline the CSS, and load images from another domain or embed them as data: URLs, since requests to the project's own domain get the maintenance page too.

What keeps working

  • The app and its services keep running. They can still talk to each other on the project's private network, and cron-style work inside them continues.
  • Published ports (a database's Public access, game or mail ports) aren't behind the edge, so they stay reachable.
  • Certificates keep renewing, and the panel, API and webhooks are served on Synq's own domain, not the project's.
  • Deploys. You can deploy while maintenance is on; visitors keep seeing the page until you switch it off. That's the usual pattern: switch on, deploy or migrate, check, switch off.

To look at the real app while visitors see the notice, reach it without its domain: publish a Localhost port and use an SSH tunnel (see Public ports).

From the API

# Turn on with a message
curl -X PATCH -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"maintenance":{"enabled":true,"message":"Upgrading the database, back by 18:00 UTC."}}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID"

# Turn off, keeping the message for next time
curl -X PATCH -H "Authorization: Bearer $SYNQ_TOKEN" -H "Content-Type: application/json" \
  -d '{"maintenance":{"enabled":false,"message":"Upgrading the database, back by 18:00 UTC."}}' \
  "$SYNQ_URL/api/projects/$PROJECT_ID"

The body also accepts html for a custom page. The maintenance object replaces the saved one as a whole, so send the message and html you want to keep with "enabled":false (that is what the panel's switch does). {"maintenance":{"enabled":false}} also turns it off but drops a message or page you didn't send, and {"maintenance":null} turns it off and clears the saved message and custom page.

SYNQ_URL is your panel address (for example https://app.example.com).

On this page