This guide covers deployment options for the Garment Sustainability Bot.
Implementation: Rust (
poise/serenity,sqlx+ SQLite only). Ported from a now-deleted Python prototype; behaviour preserved. There is no Python runtime, no virtualenv, and no Postgres.
- Prerequisites
- Local Development
- Docker Deployment
- Cloud Deployment
- Production Considerations
- Monitoring
- Troubleshooting
- A Rust toolchain (stable;
cargo) - Discord Bot Token
- Git (for cloning repository)
- https://github.com/casey/just[`just`] for the convenience recipes
- Docker / Podman (for containerised deployment)
git clone https://github.com/hyperpolymath/gsbot.git
cd gsbot
cp .env.example .env # then edit .env: set DISCORD_TOKEN
just init # build + load sample data
just run # run the bot- Clone repository:
git clone https://github.com/hyperpolymath/gsbot.git
cd gsbot- Configure environment:
cp .env.example .env
# Edit .env and add your Discord token- Build:
just build # or: cargo build (use --release for production)- Initialize database (optional sample data):
just load-data # or: cargo run --bin gsbot-load-fixturesMigrations (migrations/0001_init.sql) are applied automatically at
startup via sqlx::migrate!; no separate migration command is required.
- Run bot:
just run # or: cargo run --bin gsbot- Configure environment:
cp .env.example .env
# Edit .env with your Discord token- Build and run (compose builds with
dockerfile: Containerfile):
docker compose up -d- View logs:
docker compose logs -f bot- Stop bot:
docker compose down- Build image:
docker build -t gsbot:latest -f Containerfile .- Run container (multi-stage image; non-root
gsbotuser;ENTRYPOINT ["/usr/local/bin/gsbot"]):
docker run -d \
--name gsbot \
--env-file .env \
-v "$(pwd)/data:/app/data" \
-v "$(pwd)/logs:/app/logs" \
gsbot:latest- View logs:
docker logs -f gsbotThe SQLite database lives under /app/data (a declared VOLUME). Mount a
host directory or named volume there so data survives container restarts.
SQLite is the only supported backend — there is no Postgres option.
The bot is a single static-ish Rust binary plus a SQLite file. Any host
that can run a Linux container or a long-lived process works. Provide a
persistent volume for data/ (the SQLite DB) and set DISCORD_TOKEN.
- Connect the repository or push the image built from
Containerfile. - Set environment variables in the dashboard (at minimum
DISCORD_TOKEN; optionallyDISCORD_PREFIX,DISCORD_ADMIN_IDS,LOG_FILE). - Attach a persistent volume mounted at
/app/data. - Deploy.
-
Provision a Linux VM and SSH in.
-
Install a Rust toolchain and git, e.g. via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt update && sudo apt install -y git- Clone and build:
git clone https://github.com/hyperpolymath/gsbot.git
cd gsbot
cargo build --release --bin gsbot- Configure environment:
cp .env.example .env
# edit .env: set DISCORD_TOKEN- Set up a systemd service — create
/etc/systemd/system/gsbot.service:
[Unit]
Description=Garment Sustainability Bot
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/gsbot
EnvironmentFile=/home/ubuntu/gsbot/.env
ExecStart=/home/ubuntu/gsbot/target/release/gsbot
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
- Start the service:
sudo systemctl daemon-reload
sudo systemctl enable gsbot
sudo systemctl start gsbot
sudo systemctl status gsbotEssential for production (see src/config.rs for the full list):
# Bot
DISCORD_TOKEN=your_production_token
DISCORD_PREFIX=!
DISCORD_ADMIN_IDS=comma,separated,ids
# Database (SQLite only)
DATABASE_URL=sqlite:///app/data/gsbot.db
DATABASE_ECHO=false
# Caching
ENABLE_CACHING=true
CACHE_TTL=3600
CACHE_MAXSIZE=5000
# Logging
LOG_LEVEL=INFO
LOG_FILE=/app/logs/gsbot.log
This bot uses SQLite only. The schema lives in
migrations/0001_init.sql and is applied automatically at startup via
sqlx::migrate! — there is no external migration tool to run.
Use the bundled backup binary (keeps the last 10 backups):
cargo run --bin gsbot-backup-db # or: just backup
# restore from a backup:
cargo run --bin gsbot-backup-db restore <backup-file>Schedule it from cron, e.g.:
# crontab -e
0 2 * * * cd /home/ubuntu/gsbot && ./target/release/gsbot-backup-dbYou can also export to JSON:
cargo run --bin gsbot-export-data # or: just export-data- Use environment variables /
.envfor secrets (git-excluded). - Run as non-root (the Containerfile already uses the
gsbotuser). - Keep dependencies current and audited:
cargo update cargo audit # or: just security - Lint clean before deploying:
cargo clippy --all-targets -- -D warnings
In-process cache (src/cache.rs); tune via ENABLE_CACHING, CACHE_TTL,
CACHE_MAXSIZE.
sqlx uses a connection pool (configured in src/db.rs, max 5
connections). SQLite is single-writer; keep the DB on fast local storage.
- File logging:
LOG_FILE=/app/logs/gsbot.log
- Log rotation — create
/etc/logrotate.d/gsbot:
/app/logs/gsbot.log {
daily
rotate 14
compress
delaycompress
notifempty
create 0640 gsbot gsbot
}
systemd:
[Service]
MemoryMax=512M
CPUQuota=50%
Docker Compose:
services:
bot:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
# Process status
systemctl status gsbot # systemd
docker ps # Docker
# Logs
tail -f /app/logs/gsbot.log
docker compose logs -f botTrack:
- Command usage
- Response times
- Error rates
- Database query performance
- Memory usage
- Cache hit rates
Consider Prometheus + Grafana or an error-tracking service.
Set up alerts for bot downtime, high error rates, high memory usage, and database access issues.
- Check logs:
tail -f /app/logs/gsbot.log
docker compose logs bot-
Verify token is set (
DISCORD_TOKENis required;Config::validatefails fast if missing). -
Rebuild:
cargo build --release --bin gsbot- Check the DB file path matches
DATABASE_URL(sqlite:///.../gsbot.db); the parent directory is created on startup. - Migrations are applied automatically via
sqlx::migrate!— inspect logs for migration errors. - Inspect the database with the
sqlite3CLI if needed:
sqlite3 data/gsbot.db '.tables'- Check the process:
ps aux | grep gsbot- Reduce cache size:
CACHE_MAXSIZE=1000
- Restart:
systemctl restart gsbot
docker compose restart bot- Check bot status in Discord.
- Verify gateway intents are enabled (MESSAGE_CONTENT is required).
- Check the command prefix matches
DISCORD_PREFIX. - Review error logs.
- Ensure caching is enabled.
- Keep the SQLite file on fast local storage.
- Review logs at a higher
LOG_LEVEL. - Consider more resources.
SQLite is single-writer and local; horizontal scaling of writers is not supported by design. For higher load, scale vertically or shard the bot at the gateway level (future work).
- More CPU cores
- More RAM
- Faster local storage (SSD/NVMe)
- Daily: monitor logs and errors
- Weekly: review performance metrics
- Monthly: update dependencies, back up the database
- Quarterly: security audit (
cargo audit), performance review
- Test in development first.
- Back up the database (
gsbot-backup-db). - Update dependencies:
cargo update
- Rebuild (
cargo build --release); migrations apply on next startup. - Restart the bot and monitor.
If an update fails:
- Stop the bot.
- Restore the database from a backup
(
gsbot-backup-db restore <file>). - Revert code to the previous version and rebuild.
- Restart the bot and investigate.
- GitHub Issues: https://github.com/hyperpolymath/gsbot/issues
- Documentation: README.adoc, CLAUDE.md
- Architecture: docs/ARCHITECTURE.md
- API docs: docs/API.md