# How to Deploy FreeLLMAPI Using Docker Compose: Complete Setup Guide

> Deploy FreeLLMAPI using Docker Compose with this complete setup guide. Clone the repo, configure your environment, and launch the multi-stage container for persistent storage.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: how-to-guide
- Published: 2026-08-29

---

**Deploy FreeLLMAPI by cloning the repository, copying `.env.example` to `.env`, and running `docker compose up -d` to start the multi-stage container with persistent SQLite storage.**

FreeLLMAPI is packaged as a single-container service orchestrated through Docker Compose. The [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) file in the repository root defines the complete runtime environment, including port mapping, volume persistence, and health monitoring. This guide explains how to use the official Docker Compose configuration to deploy the service locally or on a server.

## Understanding the Docker Compose Architecture

The deployment relies on two core files: [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) orchestrates the container lifecycle, while the multi-stage `Dockerfile` builds the optimized runtime image.

### The docker-compose.yml Structure

Located in the repository root, [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) defines the **freellmapi** service with the following key configurations:

- **Image source**: Pulls from `ghcr.io/tashfeenahmed/freellmapi:latest` or builds locally from the `Dockerfile`
- **Environment loading**: Uses `env_file: .env` to load configuration variables
- **Port binding**: Maps `${HOST_BIND:-127.0.0.1}:${PORT:-3001}` to container port `3001`
- **Persistent storage**: Mounts the named volume `freellmapi-data` to `/app/server/data` for SQLite persistence
- **Network access**: Includes `extra_hosts` to resolve `host.docker.internal` for host-side proxy connections
- **Health monitoring**: Runs a Node.js fetch command against `/api/ping` every 30 seconds

```yaml
services:
  freellmapi:
    image: ghcr.io/tashfeenahmed/freellmapi:latest
    build:
      context: .
      dockerfile: Dockerfile
    env_file:
      - .env
    environment:
      NODE_ENV: production
      PORT: 3001
    ports:
      - "${HOST_BIND:-127.0.0.1}:${PORT:-3001}:3001"
    volumes:
      - freellmapi-data:/app/server/data
    extra_hosts:
      - "host.docker.internal:host-gateway"
    restart: unless-stopped
    healthcheck:
      test: ["CMD","node","-e","fetch('http://127.0.0.1:3001/api/ping').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
      interval: 30s
      timeout: 5s
      start_period: 15s
      retries: 3

volumes:
  freellmapi-data:

```

### The Multi-Stage Dockerfile

The `Dockerfile` uses a three-stage build process to minimize the final image size:

1. **Stage `deps`**: Installs Python, make, and g++ for compiling native Node modules
2. **Stage `build`**: Copies the monorepo, runs `npm ci` and `npm run build`, then prunes dev dependencies
3. **Stage `runtime`**: Creates a slim image with only production `node_modules`, sets environment variables, and configures the entrypoint to handle permissions on the data directory

Key runtime features include a health-check definition (lines 83-85) and automatic permission fixing for the SQLite data directory (lines 55-60).

## Step-by-Step Deployment Guide

Follow these steps to deploy FreeLLMAPI using the official Docker Compose configuration.

### 1. Clone the Repository

```bash
git clone https://github.com/tashfeenahmed/freellmapi.git
cd freellmapi

```

### 2. Configure Environment Variables

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

```bash
cp .env.example .env

```

Edit `.env` with your preferred settings:

```dotenv

# Network binding (127.0.0.1 for localhost-only, 0.0.0.0 for LAN access)

HOST_BIND=127.0.0.1

# Service port

PORT=3001

# Optional: HTTP proxy for outbound LLM calls

# PROXY_URL=http://host.docker.internal:7890

# API keys for providers (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)

OPENAI_API_KEY=sk-...

```

### 3. Start the Service

Build the image and start the container in detached mode:

```bash
docker compose up -d

```

Docker Compose will build the image on first run using the multi-stage Dockerfile, then launch the container with the configured environment.

### 4. Verify the Deployment

Check container status and test the API endpoint:

```bash
docker compose ps
curl http://localhost:3001/api/ping

```

The expected response is `{"ok":true}`. The built-in health-check will automatically restart the container if this endpoint becomes unresponsive.

## Configuration and Environment Variables

The `.env` file controls critical deployment parameters. Docker Compose loads these variables via the `env_file` directive in [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml).

### Network Binding and Security

By default, `HOST_BIND` is set to `127.0.0.1`, restricting access to localhost only. This ensures single-user security by default. To expose FreeLLMAPI to your LAN or the internet, change this value:

```dotenv
HOST_BIND=0.0.0.0

```

After modifying `.env`, restart the service:

```bash
docker compose down
docker compose up -d

```

### Proxy Configuration

For users running local proxies (e.g., on port 7890), the `extra_hosts` entry in [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) enables `host.docker.internal` resolution. Set your proxy URL in `.env`:

```dotenv
PROXY_URL=http://host.docker.internal:7890

```

This routes all outbound LLM API requests through your host-side proxy.

## Data Persistence and Volume Management

The `freellmapi-data` Docker volume mounts to `/app/server/data` inside the container, storing the SQLite database permanently. This persists across container restarts and updates.

To inspect the volume:

```bash
docker volume inspect freellmapi-data

```

To reset the database (destructive):

```bash
docker compose down
docker volume rm freellmapi-data
docker compose up -d

```

This removes all stored data and creates a fresh SQLite database on next startup.

## Health Checks and Monitoring

Both the `Dockerfile` and [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) define identical health-check mechanisms. Every 30 seconds, the container executes a Node.js script that fetches `http://127.0.0.1:3001/api/ping`. If the check fails three consecutive times, Docker marks the container as unhealthy and restarts it according to the `unless-stopped` policy.

Monitor health status with:

```bash
docker compose ps
docker inspect --format='{{.State.Health.Status}}' freellmapi-freellmapi-1

```

## Summary

- **Docker Compose orchestration**: The [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) file defines the complete service configuration, including ports, volumes, and health checks
- **Multi-stage build**: The `Dockerfile` creates an optimized runtime image using separate `deps`, `build`, and `runtime` stages
- **Secure defaults**: `HOST_BIND` defaults to `127.0.0.1` for localhost-only access, preventing accidental internet exposure
- **Persistent storage**: The named volume `freellmapi-data` ensures SQLite data survives container restarts
- **Proxy support**: The `extra_hosts` configuration enables `host.docker.internal` for routing through host-side proxies
- **Health monitoring**: Automatic health-checks against `/api/ping` ensure service availability

## Frequently Asked Questions

### What ports does FreeLLMAPI use by default?

By default, FreeLLMAPI listens on port `3001` inside the container. The [`docker-compose.yml`](https://github.com/tashfeenahmed/freellmapi/blob/main/docker-compose.yml) maps this to `${PORT:-3001}` on your host, which defaults to `3001`. You can override this by setting the `PORT` variable in your `.env` file.

### How do I reset the SQLite database in FreeLLMAPI?

Stop the container, remove the `freellmapi-data` volume, and restart. Run `docker compose down`, then `docker volume rm freellmapi-data`, and finally `docker compose up -d`. This creates a fresh database in `/app/server/data`.

### Can I run FreeLLMAPI behind a reverse proxy?

Yes. Set `HOST_BIND=127.0.0.1` in your `.env` file to bind to localhost only, then configure your reverse proxy (Nginx, Traefik, etc.) to forward requests to `127.0.0.1:3001`. This keeps the API secure while exposing it through your proxy.

### How do I update FreeLLMAPI to the latest version?

Pull the latest image and rebuild: `docker compose pull` followed by `docker compose up -d`. This downloads the newest `ghcr.io/tashfeenahmed/freellmapi:latest` image and recreates the container while preserving your `freellmapi-data` volume.