# Discord Bot Hosting

> Host your Discord bot on FadeHost, deployed straight from a GitHub repository. Your bot runs 24/7 in a secure, isolated container and redeploys...

Source: https://fadehost.com/docs/discord-bot-hosting/

Host your Discord bot on FadeHost, deployed straight from a GitHub repository. Your bot runs 24/7 in a secure, isolated container and **redeploys automatically every time you push to GitHub**.

- **Languages:** Node.js (discord.js) and Python (discord.py), auto-detected from your repo.
- **Free tier:** your first bot is free (256 MB RAM), always-on, with no coins to grind and no daily renewals.
- **Paid tiers:** from $2/mo per bot for more RAM, more CPU, and multiple bots: Starter (1 GB), Standard (2 GB), and Pro (4 GB). See the full table below.

You'll find Bot Hosting under **Bots** in your control panel.

## Getting started

1. Push your bot to a **GitHub repository** (public or private).
2. In the panel, go to **Bots → Host a bot** and fill in:
   - **Name:** a label for your bot.
   - **Region:** pick the location closest to you.
   - **Repository URL:** e.g. `https://github.com/you/my-bot`.
   - **Bot token** and any other secrets go in **Environment variables** (see below).
3. Click **Deploy**. FadeHost clones the repo, installs dependencies, and starts your bot.

Your first bot uses the **free tier** automatically (a verified email is required). To run more bots or get more resources, add **Bot Hosting** to your subscription in the plan builder.

## Choosing a language

Leave **Language** on **Auto-detect** and we'll pick based on your repository:

| Your repo contains | Runtime | Default start command |
| --- | --- | --- |
| `package.json` | Node.js | `npm start` |
| `requirements.txt` or `pyproject.toml` | Python | `python bot.py` (or `main.py`) |

You can override the language explicitly, and you can set a custom **Start command** if your entry point differs (for example `node index.js` or `python -m mybot`). Both can be changed later from the bot's page under **Build & start**.

- **Node.js:** make sure your `package.json` has a `start` script, or set a custom start command.
- **Python:** put your dependencies in `requirements.txt`. Your entry point should be `bot.py` or `main.py`, or set a custom start command.

## Build step (TypeScript, bundlers, monorepos)

Every deploy runs three things in order: the **install**, the **build command**, then the **start command**.

If your bot has to be compiled before it runs (TypeScript, esbuild, tsup, a bundled `dist/` folder), you do not have to commit the compiled files. Leave the build command blank and FadeHost detects the build:

- When the file your start command runs is **not in the repository** (for example `node dist/index.js` with `dist` in `.gitignore`) and your `package.json` has a `build` script, FadeHost installs your `devDependencies` and runs that script before starting the bot.
- In a **workspace** (pnpm, npm or Yarn workspaces), FadeHost builds only the package the bot starts, plus the workspace packages it depends on. A start command of `node artifacts/api-server/dist/index.mjs` runs `pnpm --filter "@workspace/api-server..." --if-present run build`, so a sibling web app in the same repository never has to build.
- A committed entry file is never built over: a repository whose `index.js` is in git starts as before, even if it has a `build` script.

To build differently, set a **Build command** on your bot's page (or when creating it). It runs on every deploy, exactly as written, for example:

```
pnpm --filter @workspace/api-server run build
```

The build runs with your `devDependencies` installed and most of the bot's memory available to Node. Its output is in the **live console**: a failed build prints its error there, and every restart repeats one line naming the file the build never produced, so you always know why the bot is not starting. Fix the build in your repository (or the Build command) and press **Redeploy**.

The **start command** and **branch** are editable on the same page. Saving redeploys the bot with the new settings.

## Environment variables

Your bot token and any config (API keys, database URLs, prefixes) are stored as **environment variables** and injected into your bot at runtime, and they're never committed to your repo.

- **On create:** add them in the **Environment variables** box, one `KEY=value` per line.
- **Editing later:** open your bot → **Environment** → edit the values → **Save & redeploy**. Your bot restarts with the new values. There's no need to delete and recreate it.

Environment variable names must start with a letter or underscore (e.g. `DISCORD_TOKEN`, `DATABASE_URL`).

## Web address (a public URL for your bot or app)

A paid bot or app can have its own public address: `https://<name>.fadehost.app`, with HTTPS out of the box. Use it for a dashboard, OAuth2 redirect URLs, incoming webhooks or a status page. It costs $2 a month per app (the **App Hosting: Web address** add-on) and is not available on the free tier.

- **Enable it:** open the app → **Web address** card → pick a name → **Enable**. The address answers within seconds; disabling it takes it down just as fast and holds the name for a day.
- **Listen on `PORT`:** we inject `PORT` into every app container. Your web server must listen on that port and on `0.0.0.0` (not `127.0.0.1`). The card lets you change the port if your app cannot read the variable; the change takes effect at once, no restart needed.
- **`APP_URL`** is injected while the address is enabled, so redirect URLs and links can be built from it.
- **Not answering:** if the app is not listening on the port, visitors see a page saying so and the card shows "Not listening on port N". Check the console for what the app logged last.
- **Not allowed:** phishing or credential pages, proxies or tunnels (cloudflared, ngrok and friends get the app stopped), adult or illegal content, bulk file or media delivery through the proxy, and traffic far beyond fair use. Raw TCP/UDP services, outbound mail and privileged workloads are not app hosting.

### Sleeps when idle

An app with a web address can be set to sleep when nobody is using it. We stop it once
nothing has opened its address for a while, and the next visit starts it again.

- **Switch it on:** open the app → **Web address** card → **Sleeps when idle**, then pick
  how long it waits: 5 minutes up to 12 hours, 15 minutes by default. It is off unless you
  switch it on.
- **What a visitor sees:** the first request after the app fell asleep is held while the
  container starts, usually a few seconds, and then the page loads normally. If the app
  takes longer than a minute to answer, the visitor gets a page saying it is waking up and
  a refresh brings it in.
- **While it sleeps:** the status says **Sleeping**, the console still shows what the app
  logged last, and everything else works as usual. Start, Stop, Restart and Redeploy do
  what they always did.
- **If you stop the app yourself**, it stays stopped: a visit does not start an app its
  owner switched off. Start it from the panel when you want it back.
- **Good fits:** a dashboard you open now and then, an OAuth2 callback, a status page. A
  Discord bot that has to stay logged in should not sleep, and neither should anything
  that has to answer a webhook the moment it arrives, because the first request after a
  sleep waits for the boot.

### Custom domains

Use your own domain for an app instead of, or beside, its fadehost.app name. Included with the web address, up to three per app.

- **Add it:** open the app → **Web address** card → **Custom domains** → enter the full hostname you own, such as `app.yourdomain.com`.
- **Set one CNAME** at your DNS provider: the hostname you entered, pointing at your app's fadehost.app name (the card shows the exact record). If your provider cannot point the root of a domain, use a subdomain such as `www` or `app`.
- **It goes live on its own**, usually within minutes: ownership is verified and a certificate issued from the CNAME. The card shows **Waiting for DNS** until then, **Live** after. If it is still waiting after an hour, the card offers two TXT records that finish the verification by hand.
- **Keep the CNAME in place.** If it goes away, the domain stops within the hour and the card says why; set the CNAME again and it comes back. Renaming the app's address changes the CNAME target: update your record.
- **The app sees the visitor's hostname** in the `Host` header, so an app that builds links from it works as expected. Requests on a custom domain count as activity for an app that sleeps when idle.

### Health checks

Every five minutes we ask your app's address for a page. By default that is the root; set **Health check path** on the **Web address** card to a path that answers quickly, such as `/health`.

- **Three failures in a row** (a server error, or no answer at all) restart the app, once an hour at most, and you get a notification. Any answer, a 404 included, resets the count.
- A stopped app is left alone, and an app that sleeps when idle is not probed at all, because a probe would keep it awake.
- The card shows how many checks in a row have failed and when the app was last restarted for it. The console shows what the app logged before the restart.

## Auto-deploy from GitHub

Every push to your bot's branch redeploys it automatically. The easiest way is the **FadeHost GitHub App**, one click with no tokens or webhooks to configure:

1. Open your bot → **Auto-deploy on push** → **Connect GitHub**.
2. GitHub asks which repositories to grant access to. Pick your bot's repo (or your whole account) and click **Install**.
3. You're sent back to the panel, and from then on every `git push` to your bot's branch clones the latest code, reinstalls dependencies, and restarts your bot.

The panel shows the **last deployed commit** on the bot, and a toast pops up live when a push lands.

You can manage or uninstall the App anytime from your GitHub **Settings → Applications**. One install covers all your bots: any bot whose repo lives on a connected account auto-deploys.

### Alternative: webhook with a token

If you'd rather not install the App, the classic path still works:

1. Open your bot → **Auto-deploy** → **Use a token instead** (or **Set it up manually** to get the **Payload URL** and **Secret**).
2. For manual setup, in your GitHub repo: **Settings → Webhooks → Add webhook**, then paste the Payload URL, set **Content type** to `application/json`, paste the Secret, choose **Just the push event**, and save.

## Private repositories

Two options:

- **GitHub App (recommended):** connect GitHub as described above. Installing the App on a private repo is all it takes. FadeHost fetches short-lived access tokens on every deploy; you never handle credentials.
- **Access token:** add a **GitHub access token** (with read access to the repo) when you create the bot. FadeHost uses it only to clone your code.

## Team sharing

Share a bot with your team from the bot's page → **Team access**. Pick the team and an access level:

- **Operate:** members can see the bot, watch the live console and logs, and start/stop/restart/redeploy.
- **Full:** members can additionally edit **environment variables** and manage the **database**. Only grant this to people you trust: it exposes your bot token and other secrets.

Deleting the bot and changing the sharing itself always stay with the owner. Members see shared bots on their **Bots** page with a *Shared with you* badge (they need the team selected as their active team).

## Databases (one click: MySQL, PostgreSQL or Redis)

A paid bot or app can have its own database on your private network, in one click: open the app, **Add a database**, pick the engine. We provision it on the app's node, put the credentials into the app's environment and redeploy it. Included with paid plans; it does not use a database slot and it is deleted with the app.

| Engine | Variables in the app's environment |
| --- | --- |
| MySQL | `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_DATABASE`, `MYSQL_USER`, `MYSQL_PASSWORD`, `DATABASE_URL` |
| PostgreSQL | `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, the `PG*` names, `DATABASE_URL` |
| Redis | `REDIS_HOST`, `REDIS_PORT`, `REDIS_PASSWORD`, `REDIS_URL` |

The host only resolves from your own apps, servers and devices on the private network. The credentials are managed: you cannot edit or remove them by hand, and they go away with the database. For a database that outlives the app, or a bigger one, create it from the Databases page instead and put its `DATABASE_URL` in the app's environment yourself.

## Live console

Open your bot → **Live console** to watch its output stream **in real time**, and a green *Live* badge shows while the stream is connected. Anything your bot prints to standard output appears within a second (Python bots run with unbuffered output automatically).

## AI Crash Doctor

If your bot gets stuck in a crash loop, FadeHost notices within a minute, reads the logs, and shows a diagnosis card on the bot: **the cause in plain English plus a suggested fix**. Common failures like an invalid Discord token, missing privileged intents, or a missing dependency are identified instantly; anything trickier is analyzed by AI.

Fix the issue (usually an environment variable or a missing package), then hit **Redeploy**.

## Managing your bot

From each bot you can **Start**, **Stop**, **Restart**, **Redeploy** (pull the latest code and reinstall), edit the **Environment**, manage its **Database**, watch the **Live console**, and configure **Auto-deploy**.

## Plans & limits

| | Free | Starter | Standard | Pro |
| --- | --- | --- | --- | --- |
| Price / bot / month | $0 | $2 | $3 | $6 |
| RAM | 256 MB | 1 GB | 2 GB | 4 GB |
| vCPU | 0.25 | 1 | 1 | 3 |
| Always-on · auto-deploy | Yes | Yes | Yes | Yes |
| Node.js & Python | Yes | Yes | Yes | Yes |
| Live console · AI Crash Doctor | Yes | Yes | Yes | Yes |
| 1-click MySQL database | | Yes | Yes | Yes |
| Web address (https://name.fadehost.app) | | +$2/mo | +$2/mo | +$2/mo |
| Bots per account | 1 (verified email) | Multiple | Multiple | Multiple |

Choose a plan when you create a bot, or add Bot Hosting plans to your subscription in the plan builder. Your first bot is always free.

Every bot runs in a hardened sandbox: non-root, read-only filesystem, dropped privileges, and hard memory & CPU limits. Note that a redeploy resets your app directory to match your repo, so store any runtime data your bot writes outside the cloned code (or in a database).

## Need help?

Join our [Discord](https://discord.gg/t4Hy4X5tEq) and our team will help you get your bot online.
