How to Deploy BettaFish Using Docker-Compose: Complete Setup Guide
Deploy BettaFish in minutes by copying .env.example to .env, configuring your credentials, and running docker compose up -d to launch the Flask UI on port 5000 and PostgreSQL on port 5444.
BettaFish is an open-source AI agent platform that combines Flask and Streamlit interfaces with a PostgreSQL backend. This guide walks you through the complete process to deploy BettaFish using docker-compose based on the official 666ghj/bettafish repository structure.
Docker-Compose Architecture Overview
The deployment consists of two services defined in docker-compose.yml at the repository root. This two-service stack isolates the application logic from data persistence, allowing each component to scale and restart independently.
The BettaFish Application Service
The bettafish container runs the main Flask application and three Streamlit agents:
- Image:
ghcr.io/666ghj/bettafish:latest(GitHub Container Registry) - Alternative Mirror:
ghcr.nju.edu.cn/666ghj/bettafish:latest(available for regions with slow GitHub connectivity) - Ports:
5000:5000for the Flask UI8501:8501for the Insight agent8502:8502for the Media agent8503:8503for the Query agent
- Volumes: Mounts for
./logs,./final_reports,./.env, and engine-specific output directories (insight_engine_streamlit_reports,media_engine_streamlit_reports,query_engine_streamlit_reports) - Environment:
PYTHONUNBUFFERED=1ensures real-time logging;STREAMLIT_SERVER_ENABLE_FILE_WATCHER=falsedisables hot-reload to prevent Docker volume conflicts
The PostgreSQL Database Service
The db container provides persistent storage for the Insight engine:
- Image:
postgres:15 - Port mapping:
${POSTGRES_PORT:-5444}:5432(defaults to host port 5444) - Credentials: Reads
POSTGRES_USER,POSTGRES_PASSWORD, andPOSTGRES_DBfrom the.envfile via theenv_filedirective - Persistent storage:
./db_data:/var/lib/postgresql/datapreserves database files across container restarts - Networking: The
bettafishservice connects using the hostnamedbas defined in the compose network
Configuration Prerequisites
Before deploying, ensure you have Docker Engine 20.10+ and Docker Compose v2.0+ installed. The application requires a configured .env file located at the project root, which both services read at runtime according to the config.py Pydantic settings class.
Creating the Environment File
The repository includes .env.example as a configuration template. Create your production environment file by copying this template:
cp .env.example .env
Edit .env to configure the following required values:
- Database settings: Set
POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB, and optionallyPOSTGRES_PORT(default 5444) - LLM API keys: Add your API keys for the Query, Media, and Insight agents as specified in the template
- Application paths: Ensure volume mount paths in
docker-compose.ymlmatch your host directory structure
Step-by-Step Deployment Guide
Follow these commands to deploy BettaFish using docker-compose from the repository root:
- Clone the repository
git clone https://github.com/666ghj/bettafish.git
cd bettafish
- Configure environment variables
cp .env.example .env
# Edit .env with your database credentials and API keys
- Optional: Configure image mirror
If you experience slow downloads from GitHub Container Registry, edit docker-compose.yml and switch to the commented mirror:
# Comment out the default image
# image: ghcr.io/666ghj/bettafish:latest
# Uncomment the mirror
image: ghcr.nju.edu.cn/666ghj/bettafish:latest
- Launch the stack
docker compose up -d
- Verify service status
docker compose ps
Both containers should display status "Up". The bettafish service exposes the Flask UI on port 5000, while Streamlit agents run on ports 8501 (Insight), 8502 (Media), and 8503 (Query).
- Access the application
- Main Flask Interface: http://localhost:5000
- Insight Agent: http://localhost:8501
- Media Agent: http://localhost:8502
- Query Agent: http://localhost:8503
Troubleshooting Common Deployment Issues
If services fail to start or connections are refused, verify these common configuration problems:
Connection refused on port 5000
- Cause: The
bettafishcontainer is still initializing or has crashed due to a missing.envfile - Fix: Check logs with
docker compose logs bettafishto identify startup errors. Ensure.envexists at the project root with validPOSTGRES_USERandPOSTGRES_PASSWORDvalues
Database authentication failures
- Cause: Mismatch between credentials in
.envand the initialized PostgreSQL data directory - Fix: If you changed passwords after the first run, the existing data in
./db_dataconflicts with new credentials. Rundocker compose down -vto remove the persistent volume, thendocker compose up -dto reinitialize the database with current.envvalues
Slow image pulls or timeout errors
- Cause: Network latency to
ghcr.io(GitHub Container Registry) - Fix: Edit
docker-compose.ymland uncomment the mirror image lineimage: ghcr.nju.edu.cn/666ghj/bettafish:latest. This uses the Nanjing University mirror for faster downloads in regions with slow GitHub connectivity
Streamlit file watcher crashes
- Cause: Streamlit's hot-reload feature conflicts with Docker volume mounts
- Fix: Verify that
docker-compose.ymlsetsSTREAMLIT_SERVER_ENABLE_FILE_WATCHER=falsein the environment section. If you override this locally, ensure it remains disabled to prevent container crashes during file operations
Summary
Deploying BettaFish using docker-compose requires only two configuration files and a single command:
- Two-service architecture: The
bettafishcontainer runs the Flask and Streamlit applications on ports 5000 and 8501-8503, while thedbcontainer provides PostgreSQL 15 persistence on port 5444 - Centralized configuration: Both services read database credentials and API keys from a single
.envfile mounted at the project root, as validated byconfig.py - Persistent storage: Volume mounts preserve logs, final reports, and database data in
./db_dataacross container restarts - Quick start: Run
cp .env.example .env, configure your credentials, thendocker compose up -dto access the complete AI agent platform
Frequently Asked Questions
How do I change the default database port when deploying BettaFish?
Set the POSTGRES_PORT variable in your .env file before starting the stack. The docker-compose.yml uses the syntax ${POSTGRES_PORT:-5444}, which defaults to 5444 if unset. After changing this value, run docker compose down followed by docker compose up -d to apply the new port mapping to the host.
Can I use a different PostgreSQL version than 15?
Yes, though the official docker-compose.yml specifies postgres:15. You can modify the image tag in the db service section to use postgres:16 or postgres:14. Ensure you back up any existing data in ./db_data before switching versions, as PostgreSQL major versions may require migration steps or data reinitialization.
Why does the BettaFish container fail to start with database connection errors?
The application container attempts to connect to PostgreSQL immediately on startup. If the db container is still initializing or if the credentials in .env do not match the PostgreSQL environment variables, the connection will fail. Verify that POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB are identical in both the application configuration and the database service definition. Use docker compose logs db to check PostgreSQL readiness and docker compose logs bettafish to view application connection attempts.
Is it possible to deploy BettaFish without using docker-compose?
While docker-compose is the recommended deployment method for the 666ghj/bettafish repository, you can run the containers manually using docker run commands or orchestrate them with Kubernetes. You would need to manually create the Docker network, start the PostgreSQL container with appropriate environment variables and volume mounts, then start the BettaFish container linked to that network with all required port mappings and volume configurations. The docker-compose.yml file serves as the authoritative reference for the required environment variables, port mappings, and volume paths needed for manual deployment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →