Zero‑Downtime Deploys for Discord Bots on Discloud: How the Health‑Check Swap Works
Discloud’s CLI builds a fresh container, waits for a health check, then atomically swaps routing — delivering true zero‑downtime deploys for Discord bots. This post walks through the config, a minimal discord.js example, and the trade‑offs you must manage.
29 Nov 2025, 16:03 UTC

The problem: keeping a bot online while you push updates
When you run a Discord bot on a traditional VPS, a code change usually means stopping the process, pulling the new image, and restarting — hoping the gateway reconnects before users notice. Discloud removes that manual dance by building a fresh container, waiting for a health signal, and then swapping the reverse‑proxy routing in a single atomic step. The result is a true zero‑downtime redeploy without any DNS or port juggling on your side.
How the container swap works
Discloud’s CLI command discloud push packages your local source, streams the Docker build logs, and launches a new container alongside the running one. The platform then probes the health endpoint you declare in discloud.config (HTTP /health or a raw TCP port). Only after the probe succeeds does Discloud flip the internal routing so incoming WebSocket traffic hits the new container. The old container is terminated after a short grace period, ensuring in‑flight messages finish processing.
Declarative config that travels with your code
The discloud.config file (YAML or JSON) lives in the repo root and defines everything the platform needs:
# discloud.config.yaml
runtime: nodejs20
startCommand: "node index.js"
env:
DISCORD_TOKEN: "${DISCORD_TOKEN}"
healthCheck:
path: "/health"
port: 3000
volumes:
- name: data
mountPath: /app/data
Because the config is version‑controlled, every team member gets the same runtime, environment variables, and persistent volume mounts without extra documentation.
Worked example: a minimal discord.js bot with a health endpoint
- Create the bot skeleton (run locally, Node ≥ 18):
mkdir my-bot && cd my-bot npm init -y npm install discord.js express - Add
index.jsthat starts both the Discord client and an Express health server:const { Client, GatewayIntentBits } = require('discord.js'); const express = require('express'); const app = express(); app.get('/health', (_, res) => res.send('ok')); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Health server on ${PORT}`)); const client = new Client({ intents: [GatewayIntentBits.Guilds] }); client.once('ready', () => console.log(`Logged in as ${client.user.tag}`)); client.login(process.env.DISCORD_TOKEN); - Write
discloud.config.yaml(as shown above). EnsurehealthCheck.pathmatches/healthandportmatches the Express port. - Authenticate the CLI once (requires a Discloud account):
discloud login # stores a long‑lived token in ~/.discloud/token — rotate periodically - Push the first deploy:
discloud push # watch the build log; the CLI exits only after the health probe succeeds - Verify zero‑downtime on a code change — edit a log line, run
discloud pushagain, and observe the dashboard: a new container appears, health check passes, then the old container disappears. No gateway disconnects occur.
Trade‑offs and limitations you should know
- Free‑tier sleep: after 15 minutes of inactivity the container is stopped. A
discloud wakecall or an external cron ping keeps it warm, but that adds operational friction for low‑traffic community bots. - No native horizontal scaling: Discloud runs a single container per app. High‑throughput bots must implement sharding inside the process (e.g.,
discord.js’sAutoSharder) rather than relying on platform replicas. - Health‑check requirement: bots that only open a WebSocket gateway must expose a dummy HTTP
/healthendpoint, otherwise the deploy hangs and rolls back. - Persistent volumes are ephemeral across plan migrations: a volume mounted at
/app/datasurvives container restarts but not region or plan changes — back up manually if you need durability. - Token hygiene: the CLI stores a long‑lived API token in
~/.discloud/token. Rotate it regularly (discloud token:rotate) and never commit it to source control.
Actionable next steps
- Add a
/healthendpoint to any existing bot that lacks one. - Commit a
discloud.configalongside your code and rundiscloud pushin a staging app to confirm the swap behaves as expected. - Set a calendar reminder to rotate the CLI token every 90 days.
- Check the current pricing page for CPU, RAM, and monthly deploy‑minute limits before promoting a bot to production — these values have changed several times since 2023.
With the health‑check‑driven container swap, Discloud gives you a Heroku‑like deploy experience tailored for Discord bots, but you still own the responsibility for sharding, wake‑up logic, and token rotation. Verify the current limits, test a rolling redeploy in a test guild, and you’ll have a reliable, low‑maintenance pipeline for every future update.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.