Skip to content

Container Installation

Jerad Berhow edited this page Oct 13, 2026 · 5 revisions

Container Installation

Running PariahBot in Docker on a Linux host, from the published image ghcr.io/cosmiccubicle/pariahbot. It's the same bot as the systemd install on Host Installation; pick one or the other. Complete Bot Setup first, because you'll need the token and application ID.

On AWS or Azure, start with AWS Hosting or Azure Hosting, which set up the machine and then come back here.

Container or systemd?

Container (this page) systemd (Host-Installation)
Host Any Linux with Docker, amd64 or arm64 Debian or Ubuntu
Node.js on the host Not needed, it's inside the image Installed by the script, through nvm
Updates Pulls a newer image (optional job, every 15 minutes) Pulls new commits from git (optional job, every 15 minutes)
Runs Builds of main only Any branch you point it at
Where things live /opt/pariahbot-container, plus two Docker volumes /opt/PariahBot

Both ask the same questions, use the same hom.env settings, and run the dashboard the same way. If you're not sure, the container is the simpler one to keep up to date.

Requirements

  • A Linux host, amd64 or arm64. A Raspberry Pi needs a 64-bit OS.
  • Docker Engine and its Compose plugin. On Ubuntu, the script offers to install them from Ubuntu's own packages. Elsewhere, install them first with Docker's instructions.
  • sudo access.
  • Server Members Intent switched on for your application in the Developer Portal, or the bot can't connect. See Bot Setup.
  • About 1 GB of memory and a few GB of disk. The image is about 400 MB.
  • Outbound internet access. No inbound ports: the bot connects out to Discord, and the dashboard is reached through a tunnel.

Docker Desktop (Windows, macOS) isn't supported by the script. The bot uses the host's network so the dashboard behaves exactly as on a systemd install, and Docker Desktop only offers that with host networking switched on in its settings.

Install

git clone https://github.com/CosmicCubicle/PariahBot.git
cd PariahBot
sudo ./deploy/container-setup.sh

The clone only supplies the script, compose.yaml and .env.example; the bot itself runs from the image. Keep the clone for rerunning the script later (git pull first).

The script:

  1. Checks for Docker and the Compose plugin, and offers to install them if they're missing
  2. Creates /opt/pariahbot-container and copies compose.yaml and .env.example into it
  3. Asks the same questions as the systemd install and writes the answers to /opt/pariahbot-container/hom.env (mode 600):
    • the bot token (hidden) and the application ID
    • optionally, a test server ID. Leave it empty in production, so commands register in every server (see Configuration)
    • whether to turn on the Admin-Dashboard, and if so its port, the Discord client secret (hidden) and an optional public address
    • whether the Server-Log should include the text of edited and deleted messages. Only say yes once Message Content Intent is switched on in the Developer Portal
  4. Checks whether this same bot (the same token) is also installed under systemd on this machine. If it is, it offers to stop and disable that install, remove its auto-update job, and copy its database into the container. If you say no, it stops, because two copies logged in with one token would both answer every command and both run moderation, alerts and pollers
  5. Pulls the image
  6. Offers to install the update job (below)
  7. Starts the container, which registers the slash commands, then reminds you to switch on Server Members Intent (see Bot Setup) and prints the dashboard steps if the dashboard is on

Rerunning it is safe. Pressing Enter keeps each current value, and the database is never touched. Rerun it to change settings, or to turn the dashboard on or off.

What's where

/opt/pariahbot-container/hom.env The configuration, the same variables as Configuration
/opt/pariahbot-container/compose.yaml How the container runs. Replaced each time the script runs, so don't edit it
/opt/pariahbot-container/.env Optional, for pinning a version (see below). Never created or changed by the script
/opt/pariahbot-container/update.log What the update job did
Volume pariahbot_data The database, mounted at /app/data
Volume pariahbot_logs The command audit log, mounted at /app/logs
Container pariahbot The bot itself

Operations

sudo docker ps --filter name=pariahbot        # is it running?
sudo docker logs -f pariahbot                 # live logs
sudo docker exec pariahbot tail -f logs/commands.log   # command audit log

cd /opt/pariahbot-container
sudo docker compose restart                   # restart
sudo docker compose up -d                     # apply edits to hom.env
sudo docker compose down                      # stop and remove the container; data is kept

After editing hom.env by hand, use docker compose up -d, not restart. A restart keeps the settings the container was created with; up -d recreates it with the new ones. Rerunning the script does this for you.

Updates

The update job, if you installed it, checks for a newer image every 15 minutes. When there is one, it recreates the container from it and removes the old image; when there isn't, it does nothing. It writes to update.log only when it updated something or something failed.

It's /usr/local/sbin/pariahbot-container-update, run from /etc/cron.d/pariahbot-container. To update right away, run it yourself:

sudo /usr/local/sbin/pariahbot-container-update

By hand, without the job:

cd /opt/pariahbot-container
sudo docker compose pull
sudo docker compose up -d

Each start registers the slash commands again, and the database updates its own schema, so an update needs nothing else.

Image tags and pinning a version

Tag What it is
latest The newest build of main. The default
2.0.0 One release. Never changes
2.0 The newest release in the 2.0 series
sha-<commit> One specific commit, e.g. sha-116e3ed. Every build gets one

latest moves with every change merged to main, like the systemd sync job. To move only when there's a release, or to stay on one version or roll back to it, create /opt/pariahbot-container/.env with the tag you want:

PARIAHBOT_IMAGE=ghcr.io/cosmiccubicle/pariahbot:2.0

then run sudo docker compose up -d there. The update job follows the pin: on 2.0 it picks up 2.0.x releases, and on 2.0.0 or a sha- tag it never moves. Delete the line to follow latest again.

The admin dashboard

The container uses the host's network, so the dashboard listens on the host's 127.0.0.1:<DASHBOARD_PORT>, exactly as on a systemd install. Everything on Admin-Dashboard applies unchanged:

  • the redirect URL to register
  • the SSH tunnel
  • a Cloudflare Tunnel, with cloudflared installed on the host and pointing at localhost:<port>

Leave DASHBOARD_HOST blank.

To check it started:

sudo docker logs pariahbot 2>&1 | grep Dashboard

Data and backups

Everything the bot remembers is in the pariahbot_data volume, in pariahbot.sqlite. Back up that file, plus hom.env for the credentials, and you can rebuild the host from scratch.

The database is in WAL mode, so stop the bot for the moment it takes to copy:

mkdir -p ~/pariahbot-backup
cd /opt/pariahbot-container
sudo docker compose stop
sudo docker compose run --rm --no-deps --user root -v ~/pariahbot-backup:/backup \
  --entrypoint sh pariahbot -c 'cp -a data/. /backup/'
sudo docker compose start
sudo cp hom.env ~/pariahbot-backup/

To restore onto a new host, run the install first so the volume exists, then:

cd /opt/pariahbot-container
sudo docker compose down
sudo docker compose run --rm --no-deps --user root -v ~/pariahbot-backup:/backup:ro \
  --entrypoint sh pariahbot -c 'rm -f data/pariahbot.sqlite* && cp /backup/pariahbot.sqlite* data/ && chown node:node data/*'
sudo docker compose up -d

Moving from a systemd install

Run the container setup on the same machine, with the same bot token. Step 4 above stops and disables the systemd service, removes its auto-update job, and offers to copy /opt/PariahBot/data into the container. That copy only happens if the container has no database yet. /opt/PariahBot itself is left in place, so you can remove it once you're happy.

To go back, stop the container first (sudo docker compose down in /opt/pariahbot-container), copy the database out (as in the backup above) over /opt/PariahBot/data/, then sudo systemctl enable --now pariahbot.service. deploy/setup.sh refuses to run while the container is running the same bot.

Running it without Compose

The script and Compose are the supported way, but the image runs on its own:

sudo docker run -d --name pariahbot --restart unless-stopped --network host \
  --env-file hom.env \
  -v pariahbot_data:/app/data -v pariahbot_logs:/app/logs \
  ghcr.io/cosmiccubicle/pariahbot:latest

On Docker's own network instead of the host's, set DASHBOARD_HOST=0.0.0.0 and publish the port on the host's loopback only, with the same number on both sides (the dashboard only answers to localhost:<DASHBOARD_PORT> or DASHBOARD_PUBLIC_URL):

  -p 127.0.0.1:8080:8080

Building the image yourself

docker build -t pariahbot:local .

Then set PARIAHBOT_IMAGE=pariahbot:local in /opt/pariahbot-container/.env. Don't install the update job with a local build: it would fail to pull it every 15 minutes.

Troubleshooting

  • The container keeps restarting. Run sudo docker logs pariahbot. The causes are the same as on Troubleshooting → The bot won't start.
  • pull access denied or unauthorized pulling the image. Check the name, ghcr.io/cosmiccubicle/pariahbot, and any PARIAHBOT_IMAGE in .env.
  • A change to hom.env did nothing. Use sudo docker compose up -d, not restart (see Operations).
  • The dashboard won't load. See Admin-Dashboard → Troubleshooting. The port in your SSH tunnel and redirect URL must match DASHBOARD_PORT.

Next

Clone this wiki locally