# How to Configure Different Database Backends in AxonHub: TiDB, PostgreSQL, MySQL, and SQLite

> Easily configure AxonHub with various database backends like TiDB PostgreSQL MySQL and SQLite using config.yml or environment variables No code changes needed for flexible data management

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

---

**AxonHub supports SQLite, MySQL, PostgreSQL, and TiDB by setting the `db.dialect` and `db.dsn` fields in [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) or via `AXONHUB_DB_*` environment variables, with no code changes required.**

To configure different database backends in AxonHub, you modify the global configuration loaded at startup. The repository `looplj/axonhub` uses a centralized configuration system defined in [`conf/conf.go`](https://github.com/looplj/axonhub/blob/main/conf/conf.go) and database-specific settings in [`internal/server/db/config.go`](https://github.com/looplj/axonhub/blob/main/internal/server/db/config.go). This guide explains how to switch between SQLite (default), MySQL, PostgreSQL, and TiDB using YAML files or environment variables.

## Understanding AxonHub's Database Configuration Architecture

AxonHub initializes its database connection through the `conf.Load()` function, which populates a global `conf.Config` struct. The database-specific subset is defined separately to keep concerns isolated.

### The Config Struct

In [`internal/server/db/config.go`](https://github.com/looplj/axonhub/blob/main/internal/server/db/config.go), the database configuration is typed as:

```go
type Config struct {
    Dialect string `conf:"dialect" yaml:"dialect" json:"dialect"`
    DSN     string `conf:"dsn" yaml:"dsn" json:"dsn"`
    Debug   bool   `conf:"debug" yaml:"debug" json:"debug"`
}

```

- **Dialect**: The database driver identifier (e.g., `sqlite3`, `mysql`, `postgres`).
- **DSN**: The Data Source Name (connection string) specific to the driver.
- **Debug**: Enables SQL logging when set to `true`.

### Default Values

The `conf.setDefaults` function in [`conf/conf.go`](https://github.com/looplj/axonhub/blob/main/conf/conf.go) establishes fallback values for local development:

| Setting | Default Value |
|---------|---------------|
| `db.dialect` | `sqlite3` |
| `db.dsn` | `file:axonhub.db?cache=shared&_fk=1&journal_mode=WAL` |
| `db.debug` | `false` |

These defaults point to a local SQLite file with foreign key support and Write-Ahead Logging enabled.

## Supported Database Backends and Connection Strings

AxonHub uses **Ent** as its ORM, which supports any driver compatible with the dialect strings below. The following table maps each supported backend to its dialect identifier and typical DSN format:

| Backend | Dialect | Driver Package | DSN Example |
|---------|---------|----------------|-------------|
| **SQLite** | `sqlite3` | `modernc.org/sqlite` (bundled) | `file:./axonhub.db?_fk=1&journal_mode=WAL` |
| **MySQL** | `mysql` | `github.com/go-sql-driver/mysql` | `user:password@tcp(127.0.0.1:3306)/axonhub?parseTime=true` |
| **PostgreSQL** | `postgres` | `github.com/jackc/pgx/v5/stdlib` | `postgres://user:password@localhost:5432/axonhub?sslmode=disable` |
| **TiDB** | `mysql` | `github.com/go-sql-driver/mysql` | `user:password@tcp(tidb-host:4000)/axonhub?parseTime=true` |

**Note on TiDB**: Because TiDB is MySQL-compatible, you use the `mysql` dialect with a DSN pointing to your TiDB cluster (default port `4000`).

## Configuration Methods

You can inject these settings via **YAML configuration files** or **environment variables**. Environment variables take precedence over file-based configuration.

### YAML Configuration File

AxonHub searches for [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) (or [`config.yaml`](https://github.com/looplj/axonhub/blob/main/config.yaml)) in the following order:

1. Current working directory ([`./config.yml`](https://github.com/looplj/axonhub/blob/main/./config.yml))
2. [`/etc/axonhub/config.yml`](https://github.com/looplj/axonhub/blob/main//etc/axonhub/config.yml)
3. `$HOME/.config/axonhub/config.yml`
4. [`./conf/config.yml`](https://github.com/looplj/axonhub/blob/main/./conf/config.yml) (relative to binary)

Create a [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) with the following structure:

```yaml
db:
  dialect: postgres
  dsn: "postgres://axon:secret@localhost:5432/axonhub?sslmode=disable"
  debug: false

```

### Environment Variables

For containerized deployments (Docker, Kubernetes), use environment variables prefixed with `AXONHUB_`:

```bash
export AXONHUB_DB_DIALECT=mysql
export AXONHUB_DB_DSN="user:pass@tcp(mysql:3306)/axonhub?parseTime=true"
export AXONHUB_DB_DEBUG=true

```

These variables override any values specified in [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml).

## Practical Configuration Examples

### Switching from SQLite to PostgreSQL

To migrate from the default SQLite backend to PostgreSQL, create [`./conf/config.yml`](https://github.com/looplj/axonhub/blob/main/./conf/config.yml):

```yaml
db:
  dialect: postgres
  dsn: "postgres://axonuser:axonpass@localhost:5432/axonhub?sslmode=disable"
  debug: true

```

With `debug: true`, AxonHub logs all SQL queries to stdout, allowing you to verify the PostgreSQL connection on startup.

### Docker and Kubernetes Environment Setup

In a `Dockerfile` or Kubernetes manifest, hardcode the environment variables to ensure the application connects to the correct database service:

```dockerfile

# Dockerfile

ENV AXONHUB_DB_DIALECT=mysql
ENV AXONHUB_DB_DSN="root:secret@tcp(mysql-service:3306)/axonhub?parseTime=true"
ENV AXONHUB_DB_DEBUG=false

```

For Kubernetes, use a Secret for the DSN:

```yaml

# deployment.yaml

env:
  - name: AXONHUB_DB_DIALECT
    value: "postgres"
  - name: AXONHUB_DB_DSN
    valueFrom:
      secretKeyRef:
        name: axonhub-db-secret
        key: dsn

```

### Connecting to TiDB

Since TiDB is MySQL-compatible, use the `mysql` dialect with a TiDB-specific host and port (default `4000`):

```yaml

# config.yml for TiDB

db:
  dialect: mysql
  dsn: "tidb_user:tidb_pass@tcp(tidb.example.com:4000)/axonhub?parseTime=true"
  debug: false

```

No additional driver installation is required; the existing MySQL driver handles the TiDB protocol.

## Summary

- **Configuration Location**: Database settings are defined in [`internal/server/db/config.go`](https://github.com/looplj/axonhub/blob/main/internal/server/db/config.go) and loaded via `conf.Load()` in [`conf/conf.go`](https://github.com/looplj/axonhub/blob/main/conf/conf.go).
- **Defaults**: AxonHub defaults to **SQLite** (`sqlite3`) with a local file for zero-configuration startup.
- **Supported Backends**: **SQLite**, **MySQL**, **PostgreSQL**, and **TiDB** (via MySQL dialect) are supported through Ent ORM.
- **Configuration Methods**: Use [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) in searched paths (current dir, `/etc/axonhub/`, `$HOME/.config/axonhub/`) or environment variables (`AXONHUB_DB_DIALECT`, `AXONHUB_DB_DSN`, `AXONHUB_DB_DEBUG`).
- **Driver Requirements**: All required drivers (SQLite, MySQL, PostgreSQL) are bundled; no manual driver installation is necessary.

## Frequently Asked Questions

### How do I switch from SQLite to MySQL in AxonHub?

Create a [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) file in your working directory or `/etc/axonhub/` with the `db.dialect` set to `mysql` and provide a valid MySQL DSN in `db.dsn`. For example: `user:password@tcp(localhost:3306)/axonhub?parseTime=true`. Restart AxonHub to apply the changes.

### Does AxonHub require code changes to support TiDB?

No code changes are required. TiDB is compatible with the MySQL protocol, so you should set `db.dialect` to `mysql` and configure the `db.dsn` to point to your TiDB cluster (typically port `4000`). The existing MySQL driver included in AxonHub handles the connection automatically.

### What environment variables override the database configuration?

AxonHub checks for `AXONHUB_DB_DIALECT`, `AXONHUB_DB_DSN`, and `AXONHUB_DB_DEBUG`. These environment variables take precedence over values defined in [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml). This is particularly useful for Docker containers and Kubernetes deployments where file-based configuration is less flexible.

### Where does AxonHub look for the config.yml file?

The configuration loader searches for [`config.yml`](https://github.com/looplj/axonhub/blob/main/config.yml) in the following order: the current working directory ([`./config.yml`](https://github.com/looplj/axonhub/blob/main/./config.yml)), [`/etc/axonhub/config.yml`](https://github.com/looplj/axonhub/blob/main//etc/axonhub/config.yml), `$HOME/.config/axonhub/config.yml`, and finally [`./conf/config.yml`](https://github.com/looplj/axonhub/blob/main/./conf/config.yml) relative to the binary location. The first file found is used.