> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinykit.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker

> Run tinykit in a Docker container

Deploy tinykit using Docker for consistent, reproducible deployments on any platform.

## Quick Start

```bash theme={null}
# Clone the repository
git clone https://github.com/tinykit-studio/tinykit.git
cd tinykit

# Build the image
docker build -f deploy/docker/Dockerfile -t tinykit .

# Run the container
docker run -d \
  -p 3000:3000 \
  -e LLM_PROVIDER=anthropic \
  -e LLM_API_KEY=your-api-key \
  -e POCKETBASE_ADMIN_EMAIL=admin@example.com \
  -e POCKETBASE_ADMIN_PASSWORD=your-password \
  -v tinykit-data:/app/pocketbase/pb_data \
  --name tinykit \
  tinykit
```

Access at `http://localhost:3000/tinykit`

***

## Dockerfile

tinykit includes a production-ready Dockerfile:

```dockerfile theme={null}
FROM node:20-alpine

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --production=false

# Copy app
COPY . .

# Build
RUN npm run build

# Create directories for runtime
RUN mkdir -p pocketbase/pb_data workspace

# Expose port
EXPOSE 3000
ENV PORT=3000
ENV HOST=0.0.0.0

# Start
CMD ["./start.sh"]
```

***

## Environment Variables

Pass environment variables with `-e`:

```bash theme={null}
docker run -d \
  -e LLM_PROVIDER=anthropic \
  -e LLM_API_KEY=sk-ant-... \
  -e LLM_MODEL=claude-sonnet-4-20250514 \
  -e POCKETBASE_ADMIN_EMAIL=admin@example.com \
  -e POCKETBASE_ADMIN_PASSWORD=securepassword123 \
  tinykit
```

Or use an env file:

```bash theme={null}
# Create .env.production
cat > .env.production << EOF
LLM_PROVIDER=anthropic
LLM_API_KEY=sk-ant-...
LLM_MODEL=claude-sonnet-4-20250514
POCKETBASE_ADMIN_EMAIL=admin@example.com
POCKETBASE_ADMIN_PASSWORD=securepassword123
EOF

# Run with env file
docker run -d --env-file .env.production tinykit
```

***

## Data Persistence

<Warning>
  Always use a volume for `/app/pocketbase/pb_data` to persist your database across container restarts.
</Warning>

### Named Volume (Recommended)

```bash theme={null}
docker run -d \
  -v tinykit-data:/app/pocketbase/pb_data \
  tinykit
```

### Bind Mount

```bash theme={null}
docker run -d \
  -v /path/on/host/pb_data:/app/pocketbase/pb_data \
  tinykit
```

***

## Docker Compose

For easier management, use Docker Compose:

```yaml theme={null}
# docker-compose.yml
version: '3.8'

services:
  tinykit:
    build:
      context: .
      dockerfile: deploy/docker/Dockerfile
    ports:
      - "3000:3000"
    environment:
      - LLM_PROVIDER=anthropic
      - LLM_API_KEY=${LLM_API_KEY}
      - LLM_MODEL=claude-sonnet-4-20250514
      - POCKETBASE_ADMIN_EMAIL=admin@example.com
      - POCKETBASE_ADMIN_PASSWORD=${POCKETBASE_ADMIN_PASSWORD}
    volumes:
      - tinykit-data:/app/pocketbase/pb_data
    restart: unless-stopped

volumes:
  tinykit-data:
```

Run with:

```bash theme={null}
# Set secrets in environment or .env file
export LLM_API_KEY=sk-ant-...
export POCKETBASE_ADMIN_PASSWORD=securepassword123

# Start
docker compose up -d

# View logs
docker compose logs -f

# Stop
docker compose down
```

***

## Production Deployment

### With Reverse Proxy (Caddy)

```yaml theme={null}
# docker-compose.yml
version: '3.8'

services:
  tinykit:
    build:
      context: .
      dockerfile: deploy/docker/Dockerfile
    environment:
      - LLM_PROVIDER=anthropic
      - LLM_API_KEY=${LLM_API_KEY}
      - POCKETBASE_ADMIN_EMAIL=admin@example.com
      - POCKETBASE_ADMIN_PASSWORD=${POCKETBASE_ADMIN_PASSWORD}
    volumes:
      - tinykit-data:/app/pocketbase/pb_data
    restart: unless-stopped

  caddy:
    image: caddy:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy-data:/data
    restart: unless-stopped

volumes:
  tinykit-data:
  caddy-data:
```

```
# Caddyfile
app.yourdomain.com {
  reverse_proxy tinykit:3000
}
```

### With nginx

```yaml theme={null}
# docker-compose.yml
services:
  tinykit:
    # ... same as above

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - /etc/letsencrypt:/etc/letsencrypt
    restart: unless-stopped
```

***

## Health Checks

The container includes a health endpoint at `/tinykit`:

```yaml theme={null}
services:
  tinykit:
    # ...
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/tinykit"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
```

***

## Updating

```bash theme={null}
# Pull latest code
git pull

# Rebuild image
docker build -f deploy/docker/Dockerfile -t tinykit .

# Restart container
docker stop tinykit
docker rm tinykit
docker run -d \
  -v tinykit-data:/app/pocketbase/pb_data \
  --env-file .env.production \
  -p 3000:3000 \
  --name tinykit \
  tinykit
```

Or with Docker Compose:

```bash theme={null}
git pull
docker compose build
docker compose up -d
```

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Container exits immediately">
    Check logs with `docker logs tinykit`. Common issues:

    * Missing environment variables
    * Invalid API key
    * Port already in use
  </Accordion>

  <Accordion title="Pocketbase fails to start">
    Ensure the Pocketbase binary is compatible with your architecture. The default binary is for linux/amd64. For ARM (M1/M2 Mac), you may need to rebuild.
  </Accordion>

  <Accordion title="Data not persisting">
    Verify your volume mount:

    ```bash theme={null}
    docker inspect tinykit | grep Mounts -A 20
    ```

    Ensure `/app/pocketbase/pb_data` is mounted to a volume.
  </Accordion>

  <Accordion title="Permission denied errors">
    The container runs as root by default. If using bind mounts, ensure the host directory is writable.
  </Accordion>
</AccordionGroup>

***

## Resource Requirements

| Resource | Minimum | Recommended            |
| -------- | ------- | ---------------------- |
| **CPU**  | 1 core  | 2 cores                |
| **RAM**  | 512MB   | 1GB                    |
| **Disk** | 1GB     | 5GB+ (depends on data) |

Limit resources with Docker:

```bash theme={null}
docker run -d \
  --memory="1g" \
  --cpus="1.0" \
  tinykit
```
