Overview
Annie Mei only depends on a few infrastructure categories:- PostgreSQL for persistent storage
- Redis for caching
- Secret injection for environment variables
- Sentry for error tracking
- A Linux host or container platform to run the bot and, for full self-hosted account linking, the auth service
Database: PostgreSQL
What Annie Mei needs
- A PostgreSQL connection string in
DATABASE_URL - A database user with permission to run migrations on startup
- TLS enabled if your database is remote
- Optional connection pooling if your provider offers it
Setup
- Provision a PostgreSQL database with version 17 or later.
- Create a database and user for Annie Mei.
-
Get the connection string:
- Format:
postgres://user:password@host:5432/database - Add
?sslmode=requireif your provider requires TLS - Set it as
DATABASE_URL
- Format:
- Start the bot. Annie Mei runs embedded Diesel migrations automatically on startup.
Connection Pooling
If your provider offers a pooled connection string, prefer that in production:The current production deployment uses Neon, so you may still see Neon-specific examples in workflow or operational notes. They are references, not requirements.
Schema
Annie Mei uses Diesel ORM for database migrations. The schema is defined in:src/schema.rs(auto-generated, do not edit)migrations/(SQL migration files)
- User AniList account registrations
- Linked AniList usernames and AniList user IDs for registered Discord accounts
Cache: Redis
What Annie Mei needs
- A Redis connection string in
REDIS_URL - Standard Redis or TLS Redis support
- Enough memory for cached API responses
Setup
- Provision a Redis instance close to where the bot runs.
-
Get the connection string:
- Standard Redis:
redis://host:6379 - TLS Redis:
rediss://default:password@host:port - Set it as
REDIS_URL
- Standard Redis:
- Enable TLS if your provider supports or requires it.
Caching Strategy
Annie Mei caches:- AniList API responses (anime/manga data)
- MyAnimeList theme song data
- Spotify track lookups
Monitoring
Monitor Redis usage through whatever tooling your host provides:- Request count
- Memory usage
- Cache hit rate
Secrets management
What Annie Mei needs
- All required environment variables available at process start
- A way to keep secrets out of git
- A repeatable way to inject secrets into production and CI
Setup
You can provide secrets in several ways:- A local
.envfile for development - A systemd
EnvironmentFile - Docker or Kubernetes secrets
- A hosted secrets manager such as Doppler, 1Password, AWS Secrets Manager, or similar
CI/CD Integration
Doppler can also sync secrets to GitHub Actions if that matches your workflow:- Generate a service token in Doppler
- Add as
DOPPLER_TOKENin GitHub repository secrets - Use in workflows:
Monitoring: Sentry
Setup
- Create a Sentry account at sentry.io
-
Create a project:
- Platform: Rust
- Copy the DSN
- Set as
SENTRY_DSNenvironment variable
-
Configure trace sampling:
Privacy Features
Annie Mei implements privacy-focused monitoring:- User ID hashing: Discord user IDs are hashed before sending to Sentry using
USERID_HASH_SALT - Credential redaction: Database and API credentials in URLs are automatically stripped from error logs
- Hash lookup utility: Use
./annie-mei hash <user_id>to find a user’s hashed ID in Sentry
src/main.rs:146-173 for implementation details.
Debug Symbols
The CI/CD pipeline automatically uploads debug symbols to Sentry for symbolicated stack traces:SENTRY_AUTH_TOKEN: Create in Sentry settingsSENTRY_ORG: Your Sentry organization slugSENTRY_PROJECT: Your project slug
Compute / VM
Deployment target
Annie Mei can run on any Linux host that can execute the release binary and reach Discord, PostgreSQL, Redis, and the external APIs. The current production deployment uses Oracle Cloud ARM64 VMs and GitHub Actions, so the examples in this section reflect that setup.Server Setup
- Create a Linux VM or host with network access to your services.
-
Install system dependencies:
-
Create the application directory:
-
Create a systemd service (
/etc/systemd/system/annie-mei.service): -
Enable and start the service:
Health Checks
Annie Mei runs an HTTP server on port 8080 (configurable viaSERVER_PORT) for health checks:
- Load balancer health checks
- Monitoring systems
- Deployment verification
The built-in health server listens on
127.0.0.1, not 0.0.0.0. If you want remote health checks, put a reverse proxy or SSH tunnel in front of it.CI/CD: GitHub Actions
Annie Mei uses GitHub Actions for automated building, testing, and deployment.Workflows
1. Clippy Analysis (.github/workflows/rust-clippy.yml)
Runs on every PR and push to main:
- Lints code with
cargo clippy - Uploads results to GitHub Security
- Annotates PRs with warnings
2. Build and Deploy (.github/workflows/build-release.yml)
Runs on:
- Version tags (
v*.*.*) - Manual workflow dispatch
- Build ARM64 binary in Rust Docker container
- Upload debug symbols to Sentry
- Create GitHub release with binaries
- Deploy to the target host:
- Copy binary via SCP
- Validate binary (executable, dependencies, files)
- Backup current binary
- Restart systemd service
- Verify service started successfully
- Rollback on failure
Required GitHub Secrets
Set these in your GitHub repository settings: Current host deployment example:ORACLE_HOST: VM hostname or IPORACLE_USER: SSH usernameORACLE_SSH_KEY: Private SSH key
SENTRY_AUTH_TOKEN: Sentry API tokenSENTRY_ORG: Organization slugSENTRY_PROJECT: Project slug
Manual Deployment
To deploy a specific branch manually:Deployment Process
The automated deployment (.github/workflows/build-release.yml:102-139):
- Validates the new binary
- Checks library dependencies with
ldd - Verifies required files (e.g.,
mei.jpg) - Backs up the current binary
- Stops the service
- Replaces the binary
- Starts the service
- Verifies the service started successfully
- Rolls back if startup fails
Cost planning
Your costs depend on the providers you choose, the number of Discord servers using the bot, and how much API traffic you generate. Typical cost buckets are:- PostgreSQL hosting
- Redis hosting
- Compute or container runtime
- Error monitoring
- Optional secrets management
Security Best Practices
Network Security
- Restrict database access to the bot host or private network where possible
- Use TLS for PostgreSQL and Redis whenever your provider supports it
- Lock down inbound ports so only required management and health-check access is exposed
Secrets Management
- Never commit secrets to git
- Rotate credentials regularly
- Use a secrets manager if you need centralized secret management
- Limit secret access to only necessary users and services
Monitoring
- Enable Sentry alerts for error spikes
- Monitor database and Redis resource usage in your provider dashboards
- Set up uptime monitoring for the HTTP health check endpoint
- Review Sentry issues regularly
Next Steps
- Review Configuration for environment setup
- See Environment Variables for complete variable reference
- Set up monitoring alerts in Sentry
- Set up your preferred secret injection workflow for deployments
