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 read/write permissions for the bot and auth service schemas
- 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. The bot connects to PostgreSQL and expects the schema to already be in place.
Connection Pooling
If your provider offers a pooled connection string, prefer that in production:Provider-specific examples are references, not requirements. Any PostgreSQL provider works if the connection string is reachable from both services.
Schema
The auth service owns the current OAuth schema migrations. The schema is defined in:auth/migrations/(SQLx migration files in the auth service repo)
migrations/ directory contains bot-owned migrations for settings tables in the annie_mei schema. It is not used to prepare the OAuth schema.
The bot reads from the auth-service-owned oauth_credentials table. The database stores:
- OAuth credentials linking Discord accounts to AniList accounts
- AniList usernames and AniList user IDs for registered Discord accounts
- OAuth session state for in-progress and completed registration flows
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
The auth service owns HTTP health checks for the stack:/healthz for liveness and /readyz for dependency-aware readiness in load balancers, monitoring systems, and deployment verification. The Discord bot process does not expose an HTTP health server.
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
