This document explains how to deploy the internal-bot to a production environment.
The deployment process uses:
- Docker for containerization
- Docker Compose for container orchestration
- Ansible for automation
- Nginx for web server and SSL termination
The application is deployed as several containers:
- Django web app (handles webhooks)
- Discord bot (sends messages to Discord)
- Background worker (processes tasks)
- PostgreSQL database
- A server running Ubuntu
- SSH access to the server
- Domain name pointing to the server
- uv installed on your local machine (it will automatically download and install ansible, if you run it from the
make deploy/*targets.
The deployment is done in three stages using Ansible playbooks:
make deploy/provisionThis runs the first two playbooks:
01_setup.yml: Sets up server, installs Docker, creates users (nginx_user and intbot_user)02_nginx.yml: Configures Nginx with SSL certificates
make deploy/appThis runs the 03_app.yml playbook which:
- Builds Docker images
- Sets up environment variables
- Creates Docker Compose configuration
- Runs database migrations
- Starts all services
The deployment uses a separated approach with different users for different responsibilities:
-
Nginx Environment (managed by
nginx_user):- Uses its own Docker Compose file generated from
docker-compose.nginx.yml.j2 - Handles SSL termination and proxying
- Has access to port 80/443 for web traffic
- Uses its own Docker Compose file generated from
-
Application Environment (managed by
intbot_user):- Uses its own Docker Compose file generated from
docker-compose.app.yml.j2 - Runs Django app, Discord bot, worker, and database
- Doesn't need direct public internet access
- Uses its own Docker Compose file generated from
Both environments are connected via a shared Docker network called "shared_with_nginx_network". This architecture provides several benefits:
- Security: Each component runs with minimal required permissions
- Access Control: Different teams can have access to different parts (some only to app, some to both)
- Separation of Concerns: Nginx configuration changes don't affect the application
- Maintenance: Either component can be updated independently
Ansible generates two specialized Makefiles:
-
Nginx Makefile (
Makefile.nginx.j2):- Focused on SSL certificate management
- Key targets:
certbot/init-staging: Set up staging certificates (for testing)certbot/upgrade-to-prod: Upgrade to production certificatescertbot/renew: Renew existing certificatescertbot/force-reissue-PROD-certificate: Force reissue production certificates
-
Application Makefile (
Makefile.app.j2):- Focused on application management
- All commands use the
prod/prefix - Key targets:
prod/migrate: Run database migrationsprod/shell: Access Django shellprod/db_shell: Access database shellprod/manage: Run Django management commandslogs: View application logs
Deployments are tied to specific Git commits:
# Deploy specific version
make deploy/app V=abcd1234If no version is specified, the current Git commit hash is used.
The application needs these environment variables in intbot.env:
DJANGO_SECRET_KEY: Secret key for DjangoDJANGO_ALLOWED_HOSTS: Comma-separated list of allowed hostsDATABASE_URL: PostgreSQL connection stringDISCORD_BOT_TOKEN: Discord bot authentication tokenDISCORD_GUILD_ID: Discord server IDGITHUB_WEBHOOK_SECRET: Secret for GitHub webhook verificationGITHUB_TOKEN: GitHub API tokenZAMMAD_WEBHOOK_SECRET: Secret for Zammad webhook verification
An example file is available at deploy/templates/app/intbot.env.example.
- Logs can be viewed with
docker compose logs - The Django admin interface is available at
/admin/ - Server monitoring should be set up separately (not included)
Common issues:
- Webhook verification failures: Check secret keys in environment variables
- Database connection errors: Verify DATABASE_URL is correct
- Discord messages not being sent: Check DISCORD_BOT_TOKEN and permissions
For more detailed logs:
docker compose logs -f bot
docker compose logs -f web
docker compose logs -f workerOr even simpler if you want to see all of them at once
make logs