Skip to main content

Deploy with Docker

Run Chat-in-Bio in production using Docker.

Create a Dockerfile

Dockerfile
FROM python:3.12-slim AS backend

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN pip install uv && uv sync --frozen --no-dev

COPY alembic.ini alembic/ ./alembic/
COPY src/ ./src/

# Build frontend
FROM node:20-slim AS frontend
WORKDIR /app/frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm run build

# Final image
FROM python:3.12-slim
WORKDIR /app

COPY --from=backend /app/.venv /app/.venv
COPY --from=backend /app/src /app/src
COPY --from=backend /app/alembic.ini /app/
COPY --from=backend /app/alembic /app/alembic
COPY --from=frontend /app/frontend/dist /app/static

ENV PATH="/app/.venv/bin:$PATH"
ENV CHATINBIO_DATABASE_URL="sqlite+aiosqlite:///./data/chatinbio.db"

EXPOSE 8000
VOLUME /app/data

CMD ["sh", "-c", "alembic upgrade head && uvicorn chatinbio.app:app --host 0.0.0.0 --port 8000"]

Create docker-compose.yml

docker-compose.yml
services:
chatinbio:
build: .
ports:
- "8000:8000"
volumes:
- chatinbio-data:/app/data
env_file:
- .env
restart: unless-stopped

volumes:
chatinbio-data:

Configure and run

cp .env.example .env
# Edit .env with your production values

docker compose up -d

Persistent data

The SQLite database is stored in the chatinbio-data Docker volume at /app/data/chatinbio.db. Back up this volume to preserve your data.

Reverse proxy

Put this behind nginx or Caddy. Example Caddyfile for cht.bio:

Caddyfile
cht.bio {
reverse_proxy chatinbio:8000
}

Make sure your reverse proxy passes WebSocket upgrade headers for /ws/chat.