Self-Hosting with Docker
Relevant source files
The following files were used as context for generating this wiki page:Amina is designed to be containerized using Docker, allowing for a consistent and isolated environment for deployment. The project provides Docker Compose configurations for both development and production, orchestrating a multi-container setup that includes the main bot application, a Lavalink music server, a monitoring service, and an automatic update mechanism. This approach simplifies dependency management and ensures that all necessary services are running and correctly networked.
The primary method for deploying a production-ready instance is via the local.sh script, which automates the process of setting up the required configuration files and directory structure. For more details on getting started, see the Quick Start Self-Hosting Guide.
Sources: README.md:83-85, scripts/local.sh, docker-compose.prod.yml
Architecture Overview
The Docker-based architecture consists of several interconnected services that run in isolated containers but communicate over a shared Docker network. The production setup is the most comprehensive, including services for the bot logic, music, monitoring, and updates.
This diagram illustrates the high-level architecture of the production Docker environment.
Sources: docker-compose.prod.yml
Services
The production environment defined in docker-compose.prod.yml includes the following core services:
| Service | Image | Description |
|---|---|---|
amina | vikshan/amina:latest | The main Discord bot application. It connects to Discord, handles commands, and communicates with Lavalink for music playback. |
lavalink | ghcr.io/lavalink-devs/lavalink:latest | A standalone audio server that handles music streaming from sources like YouTube and SoundCloud, reducing the load on the main bot. |
uptime-kuma | louislam/uptime-kuma:nightly2 | A monitoring tool used to track the health and uptime of the amina and lavalink services. Accessible via a web interface. |
watchtower | nickfedor/watchtower:latest | An automated service that watches for updates to the running container images and automatically restarts them with the new version. |
Sources: docker-compose.prod.yml:3-100
Environments
The repository provides two distinct Docker Compose files for different use cases: development and production.
Production (docker-compose.prod.yml)
This file is optimized for a stable, live deployment.
- Uses pre-built, versioned images from a container registry (e.g.,
vikshan/amina:latest). - Includes the
uptime-kumaservice for monitoring. - Configured for
restart: unless-stoppedto ensure services recover from crashes.
Sources: docker-compose.prod.yml:3-5, docker-compose.prod.yml:81-83
Development (docker-compose.yml)
This file is tailored for local development and testing.
- Builds the
aminaimage from the localDockerfileand source code. - Mounts the local source code (
./src,./types) into the container for live-reloading. - Uses
bun --watch .to automatically restart the bot process when code changes are detected. - Does not include the
uptime-kumaservice.
Sources: docker-compose.yml:3-7, docker-compose.yml:16-17, docker-compose.yml:28-36
Service Breakdown
Amina Service
The amina service is the core of the application.
- Networking: It operates on the
amina-networkand exposes port3000for its health check endpoint. - Configuration: It loads all necessary credentials and settings from an
.envfile. For communication with the music server, it overrides the Lavalink host to use the Docker service namelavalink. - Health Check: A health check is configured to periodically query
http://localhost:3000/health. This allows Docker to monitor the bot's internal status and restart it if it becomes unresponsive.
# Excerpt from docker-compose.prod.yml
services:
amina:
image: vikshan/amina:latest
container_name: amina
restart: unless-stopped
env_file:
- .env
environment:
# Override Lavalink connection to use Docker network
LAVALINK_HOST_1: lavalink
LAVALINK_PORT_1: 2333
LAVALINK_SECURE_1: "false"
HEALTH_PORT: 3000
ports:
- "3000:3000"
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:3000/health",
]
Sources: docker-compose.prod.yml:3-28, src/config/config.ts:16
Lavalink Service
The lavalink service is essential for all music-related functionality.
- Permissions: The container is started as
user: rootto allow an entrypoint script (lavalink-entrypoint.sh) to fix file permissions before handing off control to thelavalinkuser. This is a security and operational best practice. - Configuration: It mounts a local
application.ymlfile for detailed Lavalink settings. The password is set via theLAVALINK_PASSWORD_1environment variable from the.envfile. - Health Check: Its health check queries the
/versionendpoint, using the configured password for authorization. This ensures the Lavalink server is not only running but also properly configured and accessible.
# Excerpt from docker-compose.prod.yml
lavalink:
image: ghcr.io/lavalink-devs/lavalink:latest
# ...
user: root
# ...
environment:
- LAVALINK_SERVER_PASSWORD=${LAVALINK_PASSWORD_1:-incorrect}
volumes:
- ./lavalink/application.yml:/opt/Lavalink/application.yml:ro
- ./lavalink-entrypoint.sh:/lavalink-entrypoint.sh:ro
entrypoint: ["/bin/sh", "/lavalink-entrypoint.sh"]
healthcheck:
test: [
"CMD-SHELL",
"wget --no-verbose --tries=1 --spider --header='Authorization:
${LAVALINK_PASSWORD_1:-incorrect}' http://localhost:2333/version ||
exit 1",
]
Sources: docker-compose.prod.yml:31-64
Watchtower Service
The watchtower service provides automated maintenance by keeping containers up-to-date.
- Functionality: It monitors the Docker registry for new versions of the images used by running containers (e.g.,
amina,lavalink). - Configuration: It is configured to clean up old images (
WATCHTOWER_CLEANUP=true), perform rolling restarts to minimize downtime (WATCHTOWER_ROLLING_RESTART=true), and send notifications to a Discord webhook defined byLOGS_WEBHOOKin the.envfile.
Sources: docker-compose.prod.yml:101-115, docker-compose.yml:67-81
Configuration
Proper configuration via environment variables is critical for self-hosting. The app.json file provides a comprehensive list of variables that should be present in the .env file at the root of the deployment directory.
Key Environment Variables
| Variable | Description | Default/Example | Source File |
|---|---|---|---|
BOT_TOKEN | The Discord bot token. | Required | app.json |
MONGO_CONNECTION | The connection string for the MongoDB database. | Required | app.json |
LAVALINK_HOST_1 | Host for the primary Lavalink node. | lavalink | app.json, docker-compose.prod.yml |
LAVALINK_PORT_1 | Port for the primary Lavalink node. | 2333 | app.json, docker-compose.prod.yml |
LAVALINK_PASSWORD_1 | Password for the primary Lavalink node. | incorrect | app.json, docker-compose.prod.yml |
LOGS_WEBHOOK | Discord webhook URL for bot logs and Watchtower notifications. | Optional | app.json, docker-compose.prod.yml |
GEMINI_KEY | API key for Google Gemini (for AI features). | Optional | app.json |
GH_TOKEN | GitHub token for fetching changelogs. | Optional | app.json |
Sources: app.json:4-87, docker-compose.prod.yml:6-11, docker-compose.prod.yml:114
Automated Deployment (local.sh)
The project includes a shell script, local.sh, to streamline the setup of a production environment on a new machine. It handles prerequisite checks, file setup, and permissions.
The deployment flow is as follows:
Sources: scripts/local.sh
The script performs these key actions:
- Prerequisites: Checks for
gitanddocker. If on a Debian-based system, it offers to install them. It also validates Docker permissions for the current user. - Cloning: Clones the
aminarepository into a temporary directory. - File Preparation: Creates the deployment directory (default
~/amina) and copies the necessary files:docker-compose.prod.ymlis copied and renamed todocker-compose.yml..env.exampleis copied to.env(if no.envalready exists).lavalink/application.ymlandlavalink-entrypoint.share copied.
- Permissions: Sets the permissions of the
.envfile to600(read/write for owner only) for security. - Guidance: After a successful setup, it prints instructions for the user to review configurations and start the services using
docker compose up -d.
Sources: scripts/local.sh:70-245
Conclusion
The self-hosting solution for Amina using Docker and Docker Compose provides a robust, scalable, and maintainable way to run the bot and its dependencies. By containerizing each component, the system ensures service isolation and simplifies management. The inclusion of separate development and production configurations, along with an automated deployment script, caters to both developers contributing to the project and users looking to host their own instance. The addition of monitoring and automatic updates in the production stack further enhances the reliability and ease of long-term maintenance.
Sources: docker-compose.yml, docker-compose.prod.yml, scripts/local.sh