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.