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
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | Database connection string | sqlite:/data/db.sqlite |
PORT | Server port | 3000 |
HOST | Bind address | 0.0.0.0 |
GEMINI_API_KEY | Gemini API key | - |
OPENAI_API_KEY | OpenAI API key | - |
ANTHROPIC_API_KEY | Anthropic API key | - |
RUST_LOG | Log level | info |
JWT_SECRET | JWT signing secret | Auto-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
- Self-Hosted Deployment - Bare metal installation
- VPS Deployment - Cloud deployment guide
- Configuration - Detailed configuration