How to Deploy FreeLLMAPI Using Docker Compose: Complete Setup Guide

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 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 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 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
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

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:

cp .env.example .env

Edit .env with your preferred settings:


# 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:

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:

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.

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:

HOST_BIND=0.0.0.0

After modifying .env, restart the service:

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 enables host.docker.internal resolution. Set your proxy URL in .env:

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:

docker volume inspect freellmapi-data

To reset the database (destructive):

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 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:

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

Summary

  • Docker Compose orchestration: The 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 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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →