# How to Deploy AxonHub Using Docker Compose for Production

> Deploy AxonHub in production easily with Docker Compose. Clone the repo, set environment variables, and run docker-compose up -d for a seamless API gateway deployment.

- Repository: [Loop/axonhub](https://github.com/looplj/axonhub)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Deploy AxonHub in production by cloning the repository, configuring environment variables in a `.env` file, and running `docker-compose up -d` to launch the Gin-based API gateway with its supporting PostgreSQL and Redis services.**

AxonHub is a Go-based AI gateway that provides OpenAI-compatible and Anthropic-compatible APIs. When you deploy AxonHub using Docker Compose for production workloads, you orchestrate three core containerized services defined in the official [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) file located in the root of the `looplj/axonhub` repository.

## Understanding the AxonHub Container Architecture

The production deployment consists of distinct services that handle API requests, persistent storage, and caching. Each service is configured via environment variables loaded from your `.env` file.

### Core Services Overview

- **axonhub**: The primary Gin-based HTTP server that exposes the REST API on port `8090` (configurable via `AXONHUB_SERVER_PORT`). This container processes all AI gateway requests.
- **postgresql**: An embedded PostgreSQL instance used when the bundled database is enabled. This is the default configuration in [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) for quick production setups.
- **redis**: An in-memory cache container that handles request throttling, token buckets, and rate limiting across the gateway.

## Prerequisites and Environment Configuration

Before launching the stack, you must prepare the host environment and configuration files.

### Clone the Repository

Start by cloning the source code to access the compose file and configuration templates:

```bash
git clone https://github.com/looplj/axonhub.git
cd axonhub

```

### Create the Production Environment File

Copy the example environment file and customize it for your production deployment:

```bash
cp .env.example .env

```

Edit the `.env` file to set critical variables:

```bash
AXONHUB_SERVER_PORT=8090
AXONHUB_DB_DIALECT=postgres
AXONHUB_DB_DSN=postgres://user:password@postgresql:5432/axonhub?sslmode=disable
AXONHUB_LOG_LEVEL=info

```

For external managed databases, change `AXONHUB_DB_DIALECT` to `tidb` or `mysql` and update the DSN accordingly.

## Configuring the Docker Compose Stack

The [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) file in the repository root defines service dependencies, networking, and persistence.

### Service Definitions and Port Mapping

The compose file exposes the AxonHub API on the host port defined by `${AXONHUB_SERVER_PORT}`, mapping to container port `8090`:

```yaml
services:
  axonhub:
    image: ghcr.io/looplj/axonhub:latest
    env_file: .env
    ports:
      - "${AXONHUB_SERVER_PORT}:8090"
    restart: always
    depends_on:
      - postgresql
      - redis

```

### Persistent Storage and Restart Policies

Data persistence is configured via Docker volumes to ensure data survives container restarts:

```yaml
volumes:
  postgres_data:
  redis_data:

```

The `restart: always` policy ensures the gateway recovers automatically from host reboots or container failures.

## Deploying AxonHub in Production

Execute these steps to launch your production instance.

1. **Start the stack** in detached mode:
   ```bash
   docker-compose up -d
   ```

2. **Verify container status**:
   ```bash
   docker-compose ps
   ```

   All three services (axonhub, postgresql, redis) should show status `Up`.

3. **Monitor logs** for startup errors:
   ```bash
   docker-compose logs -f axonhub
   ```

4. **Test the API endpoint**:
   ```bash
   curl http://localhost:8090/v1/models \
     -H "Authorization: Bearer <YOUR_API_KEY>"
   ```

## Production Hardening and Scaling Strategies

For high-availability deployments, extend the basic compose setup with these architectural patterns.

### TLS Termination and Reverse Proxy Setup

Place a reverse proxy such as NGINX or Traefik in front of the AxonHub container to handle TLS termination. Update the compose file to remove the port mapping from the axonhub service and instead expose it only to the internal Docker network, letting the proxy route traffic securely.

### External Database Configuration

Replace the embedded PostgreSQL container with a managed database for production resilience. In [`conf/conf.go`](https://github.com/looplj/axonhub/blob/main/conf/conf.go), the configuration loader supports `tidb`, `postgres`, and `mysql` dialects. Update your `.env` file:

```bash
AXONHUB_DB_DIALECT=tidb
AXONHUB_DB_DSN=<USER>.root:<PASS>@tcp(<HOST>:4000)/axonhub?tls=true&...

```

### Horizontal Scaling and Load Balancing

Run multiple AxonHub replicas behind a load balancer by scaling the service:

```bash
docker-compose up -d --scale axonhub=3

```

Each replica connects to the same PostgreSQL and Redis instances, allowing shared state for rate limiting and token management.

### Backup and Disaster Recovery

Schedule regular backups of the PostgreSQL volume:

```bash
docker-compose exec postgresql pg_dumpall -U postgres > backup_$(date +%F).sql

```

For external databases, use the provider's native snapshot tools.

## Upgrading and Maintenance

When new versions of AxonHub are released, update the deployment without data loss:

1. **Pull the latest image**:
   ```bash
   docker-compose pull
   ```

2. **Recreate containers** with the new image:
   ```bash
   docker-compose up -d --force-recreate
   ```

3. **Verify the new version** is running:
   ```bash
   docker-compose exec axonhub /app/axonhub --version
   ```

To shut down the stack for maintenance:

```bash
docker-compose down

```

Add the `-v` flag to remove volumes only if you intend to wipe all persistent data.

## Summary

- **AxonHub** runs as a Go-based Gin server inside Docker, typically deployed alongside PostgreSQL and Redis containers defined in [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml).
- **Production deployment** requires configuring environment variables in a `.env` file, particularly `AXONHUB_DB_DIALECT` and `AXONHUB_DB_DSN` for database connectivity.
- **Data persistence** is handled through Docker volumes for PostgreSQL and Redis, ensuring state survives container restarts.
- **High availability** is achieved by placing a TLS-terminating reverse proxy in front of the stack, using external managed databases, and scaling the `axonhub` service horizontally behind a load balancer.
- **Maintenance** follows standard Docker Compose workflows: `docker-compose pull` and `up -d --force-recreate` for upgrades, and `docker-compose down` for shutdown.

## Frequently Asked Questions

### How do I configure AxonHub to use an external database instead of the embedded PostgreSQL container?

Set `AXONHUB_DB_DIALECT` to `tidb`, `postgres`, or `mysql` in your `.env` file, then provide the connection string via `AXONHUB_DB_DSN`. Remove or disable the `postgresql` service in [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) if you are using a fully external database, or keep it for local caching while pointing AxonHub to the remote instance.

### What is the default port for the AxonHub API when deployed via Docker Compose?

The container exposes port `8090` internally, which is mapped to the host port defined by the `AXONHUB_SERVER_PORT` environment variable (defaulting to `8090` in the example `.env` files). You can override this mapping in [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) if you need to run multiple instances or avoid port conflicts.

### How do I scale AxonHub horizontally to handle more traffic?

Use the Docker Compose scale command to run multiple replicas: `docker-compose up -d --scale axonhub=3`. Ensure all replicas connect to the same PostgreSQL and Redis instances so that rate limiting and token buckets remain consistent across the cluster. Place a load balancer or reverse proxy in front of the replicas to distribute incoming requests.

### Where are the configuration files loaded from when running in a Docker container?

AxonHub loads configuration primarily from environment variables, as implemented in [`conf/conf.go`](https://github.com/looplj/axonhub/blob/main/conf/conf.go). The [`docker-compose.yml`](https://github.com/looplj/axonhub/blob/main/docker-compose.yml) file specifies an `env_file: .env` directive, which injects variables into the container at runtime. You can also mount custom configuration files into the container if you prefer YAML-based configuration, though environment variables are the recommended approach for containerized deployments.