Skip to main content

Docker Deployment

Deploy Friday Dev using Docker containers for easy management and portability.

Quick Start

# Run Friday Dev with Docker
docker run -d \
--name friday-dev \
-p 3000:3000 \
-v friday-data:/data \
-e GEMINI_API_KEY=your-key \
fridaydev/friday-dev:latest

Access at: http://localhost:3000

Docker Compose

Basic Setup

Create docker-compose.yml:

version: '3.8'

services:
friday-dev:
image: fridaydev/friday-dev:latest
container_name: friday-dev
ports:
- "3000:3000"
volumes:
- friday-data:/data
environment:
- DATABASE_URL=sqlite:/data/db.sqlite?mode=rwc
- GEMINI_API_KEY=${GEMINI_API_KEY}
- RUST_LOG=info
restart: unless-stopped

volumes:
friday-data:

Run:

docker-compose up -d

Production Setup

version: '3.8'

services:
friday-dev:
image: fridaydev/friday-dev:latest
container_name: friday-dev
restart: always
volumes:
- friday-data:/data
- ./config.json:/etc/friday-dev/config.json:ro
environment:
- DATABASE_URL=sqlite:/data/db.sqlite?mode=rwc
- GEMINI_API_KEY=${GEMINI_API_KEY}
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- RUST_LOG=info
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3

nginx:
image: nginx:alpine
container_name: friday-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- friday-static:/var/www/friday-dev:ro
depends_on:
- friday-dev
restart: always

volumes:
friday-data:
friday-static:

With PostgreSQL

version: '3.8'

services:
friday-dev:
image: fridaydev/friday-dev:latest
depends_on:
- postgres
environment:
- DATABASE_URL=postgresql://friday:password@postgres/friday_dev
- GEMINI_API_KEY=${GEMINI_API_KEY}
restart: always

postgres:
image: postgres:15-alpine
environment:
- POSTGRES_USER=friday
- POSTGRES_PASSWORD=password
- POSTGRES_DB=friday_dev
volumes:
- postgres-data:/var/lib/postgresql/data
restart: always

volumes:
postgres-data:

Configuration

Environment Variables

VariableDescriptionDefault
DATABASE_URLDatabase connection stringsqlite:/data/db.sqlite
PORTServer port3000
HOSTBind address0.0.0.0
GEMINI_API_KEYGemini API key-
OPENAI_API_KEYOpenAI API key-
ANTHROPIC_API_KEYAnthropic API key-
RUST_LOGLog levelinfo
JWT_SECRETJWT signing secretAuto-generated

Using .env File

Create .env:

GEMINI_API_KEY=your-gemini-key
OPENAI_API_KEY=your-openai-key
ANTHROPIC_API_KEY=your-anthropic-key
JWT_SECRET=your-secret-key

Docker Compose automatically loads .env.

Building Custom Image

Dockerfile

FROM fridaydev/friday-dev:latest

# Add custom configuration
COPY config.json /etc/friday-dev/config.json

# Add custom themes/plugins
COPY custom-theme /app/custom-theme

# Set environment
ENV RUST_LOG=info

Build:

docker build -t my-friday-dev .

Docker Volumes

Data Persistence

# Create volume
docker volume create friday-data

# List volumes
docker volume ls

# Inspect volume
docker volume inspect friday-data

# Backup volume
docker run --rm -v friday-data:/data -v $(pwd):/backup alpine \
tar czf /backup/friday-backup.tar.gz /data

Restore Volume

docker run --rm -v friday-data:/data -v $(pwd):/backup alpine \
tar xzf /backup/friday-backup.tar.gz -C /

Networking

Bridge Network (Default)

# Create network
docker network create friday-net

# Run with network
docker run -d --network friday-net --name friday-dev fridaydev/friday-dev

Host Network

# Direct host networking
docker run -d --network host fridaydev/friday-dev

Health Checks

Built-in Health Check

# Check container health
docker inspect --format='{{.State.Health.Status}}' friday-dev

Custom Health Check

services:
friday-dev:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

Logging

View Logs

# Follow logs
docker logs -f friday-dev

# Last 100 lines
docker logs --tail 100 friday-dev

# With timestamps
docker logs -t friday-dev

Log Driver

services:
friday-dev:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

Resource Limits

services:
friday-dev:
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G

Security

Read-Only Root

services:
friday-dev:
read_only: true
tmpfs:
- /tmp
volumes:
- friday-data:/data

Non-Root User

services:
friday-dev:
user: "1000:1000"
volumes:
- friday-data:/data

Secrets

services:
friday-dev:
secrets:
- gemini_api_key
environment:
- GEMINI_API_KEY_FILE=/run/secrets/gemini_api_key

secrets:
gemini_api_key:
file: ./secrets/gemini_api_key.txt

Updates

Pull Latest Image

# Pull new image
docker pull fridaydev/friday-dev:latest

# Recreate container
docker-compose up -d --force-recreate

Automated Updates (Watchtower)

services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 86400 friday-dev

Kubernetes

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: friday-dev
spec:
replicas: 1
selector:
matchLabels:
app: friday-dev
template:
metadata:
labels:
app: friday-dev
spec:
containers:
- name: friday-dev
image: fridaydev/friday-dev:latest
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
value: "sqlite:/data/db.sqlite?mode=rwc"
- name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: friday-secrets
key: gemini-api-key
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: friday-data

Service

apiVersion: v1
kind: Service
metadata:
name: friday-dev
spec:
selector:
app: friday-dev
ports:
- port: 80
targetPort: 3000
type: LoadBalancer

Troubleshooting

Container Won't Start

# Check logs
docker logs friday-dev

# Inspect container
docker inspect friday-dev

# Try interactive mode
docker run -it fridaydev/friday-dev:latest /bin/sh

Permission Errors

# Fix volume permissions
docker run --rm -v friday-data:/data alpine chown -R 1000:1000 /data

Network Issues

# Check network
docker network inspect friday-net

# Test connectivity
docker exec friday-dev curl http://localhost:3000/api/health

Next Steps