Deployment
This deployment documentation is currently being enhanced and refined. Some sections may be incomplete or subject to change. We're actively working on comprehensive examples and troubleshooting guides for all platforms.
flAPI is designed for deployment flexibility. Available as a single binary or Docker container, it runs on any platform that supports Linux containers or x86-64 binaries.
Quick Start
🚀 Interactive Deployment Configurator
Configure your deployment with config mounting strategy
# 1. Create directory structure on host
mkdir -p ~/flapi/{config/sqls,data}
# 2. Create your flapi.yaml
cat > ~/flapi/config/flapi.yaml <<EOF
project_name: my-api
template:
path: '/config/sqls'
connections:
# Your connections here
duckdb:
db_path: /data/flapi.db
EOF
# 3. Add your SQL templates
# cp your_templates.yaml ~/flapi/config/sqls/
# 4. Create docker-compose.yml
cat > ~/flapi/docker-compose.yml <<EOF
version: '3.8'
services:
flapi:
image: ghcr.io/datazoode/flapi:latest
ports:
- "8080:8080"
volumes:
- ./config:/config:ro
- ./data:/data
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 2G
EOF
# 5. Deploy
cd ~/flapi && docker-compose up -dRequirements
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 1 vCPU | 2 vCPU | DuckDB is CPU-intensive for aggregations |
| Memory | 1 GB | 2-4 GB | Depends on cache size |
| Storage | 1 GB | 10 GB+ | For DuckDB cache persistence |
| Port | 8080 | - | Default HTTP port |
| Startup | < 100ms | - | Fast cold starts for serverless |
Configuration Management
flAPI requires configuration files to function. The base Docker image (ghcr.io/datazoode/flapi:latest) contains only the binary - you must mount your configuration to run it.
Standard Directory Structure
flAPI expects the following structure:
/config/
├── flapi.yaml # Main configuration file (required)
└── sqls/ # SQL template directory (required)
├── users.yaml # Endpoint definitions
├── products.yaml
└── orders.yaml
Minimal Example Configuration
Create flapi.yaml:
project_name: my-api
project_description: My flAPI deployment
template:
path: '/config/sqls' # Path to SQL templates
connections:
postgres:
connection_string: "postgresql://user:pass@host:5432/db"
duckdb:
db_path: /data/flapi.db # Cache database location
access_mode: READ_WRITE
Create your first endpoint sqls/users.yaml:
url-path: /users
sql: |
SELECT * FROM users
WHERE active = true
LIMIT 100
Configuration Mounting Strategies
Choose the approach that fits your deployment platform:
1️⃣ Local Volume Mount (Docker, VPS, K8s)
Best for: Development, VPS deployment, on-premises
Mount your local config directory directly into the container:
docker run -d \
-p 8080:8080 \
-v $(pwd)/config:/config:ro \
-v $(pwd)/data:/data \
ghcr.io/datazoode/flapi:latest
Advantages:
- ✅ Simple and direct
- ✅ Easy to update (edit files, restart container)
- ✅ Works with any text editor
Disadvantages:
- ❌ Requires host filesystem access
- ❌ Not suitable for serverless platforms
2️⃣ Kubernetes ConfigMap (K8s, IONOS, STACKIT)
Best for: Kubernetes deployments, multi-replica setups
Create ConfigMaps from your config files:
# Create ConfigMap for main config
kubectl create configmap flapi-config \
--from-file=flapi.yaml=./config/flapi.yaml \
--namespace=flapi
# Create ConfigMap for SQL templates
kubectl create configmap flapi-sqls \
--from-file=./config/sqls/ \
--namespace=flapi
Mount in your Deployment:
volumeMounts:
- name: config
mountPath: /config/flapi.yaml
subPath: flapi.yaml
- name: sqls
mountPath: /config/sqls
volumes:
- name: config
configMap:
name: flapi-config
- name: sqls
configMap:
name: flapi-sqls
Advantages:
- ✅ Native Kubernetes integration
- ✅ Version controlled via kubectl
- ✅ Can be updated without rebuilding images
Disadvantages:
- ❌ ConfigMap size limit (1MB)
- ❌ Requires kubectl access to update
For large SQL template collections, use PersistentVolumes instead of ConfigMaps.
3️⃣ Cloud Storage Mount (Cloud Run, Lambda, Azure)
Best for: Serverless platforms, multi-region deployments
Google Cloud Run (GCS Bucket):
# 1. Upload config
gsutil -m cp -r ./config gs://my-bucket/flapi-config/
# 2. Deploy with GCS mount
gcloud run deploy flapi \
--image ghcr.io/datazoode/flapi:latest \
--add-volume=name=config,type=cloud-storage,bucket=my-bucket \
--add-volume-mount=volume=config,mount-path=/config
AWS Lambda (EFS Mount):
# 1. Create EFS file system
aws efs create-file-system --tags Key=Name,Value=flapi-config
# 2. Mount EFS to EC2, upload config to /config
# 3. Create Lambda with EFS mount
aws lambda create-function \
--function-name flapi \
--file-system-configs "Arn=arn:aws:elasticfilesystem:...,LocalMountPath=/config"
Advantages:
- ✅ Works with serverless platforms
- ✅ Centralized configuration storage
- ✅ Can be shared across multiple instances
Disadvantages:
- ❌ Increased cold start time
- ❌ Additional cost for storage
- ❌ More complex setup
4️⃣ Baked-In Configuration (Custom Image)
Best for: Immutable deployments, CI/CD pipelines
Create a custom Docker image with config baked in:
FROM ghcr.io/datazoode/flapi:latest
# Copy configuration into image
COPY config/flapi.yaml /config/flapi.yaml
COPY config/sqls /config/sqls
# Optional: Set environment variables
ENV FLAPI_CONFIG=/config/flapi.yaml
CMD ["/app/flapi", "-c", "/config/flapi.yaml"]
Build and deploy:
docker build -t my-org/flapi:v1.0 .
docker push my-org/flapi:v1.0
Advantages:
- ✅ Self-contained, portable image
- ✅ Fastest cold start (no external mounts)
- ✅ Works on any platform
Disadvantages:
- ❌ Config changes require image rebuild
- ❌ Larger image size
- ❌ Less flexible
Never bake secrets (database passwords, API keys) into images. Use environment variables or secret management instead.
Configuration Update Strategies
| Platform | Update Method | Downtime | Rollback |
|---|---|---|---|
| Docker Compose | Edit files → docker-compose restart | < 1s | Manual (git revert) |
| Kubernetes | kubectl apply configmap → Rolling update | 0s | kubectl rollout undo |
| Cloud Run | Update GCS bucket → Redeploy | ~30s | Deploy previous revision |
| Custom Image | Rebuild → Push → Deploy | ~2-5min | Deploy previous tag |
Configuration Validation
Before deploying, validate your configuration:
# Run flAPI locally to check for errors
docker run --rm \
-v $(pwd)/config:/config \
ghcr.io/datazoode/flapi:latest \
--dry-run
# Check YAML syntax
yamllint config/flapi.yaml config/sqls/*.yaml
# Test SQL templates
# (flAPI will validate SQL on startup)
Environment Variables
Override config values using environment variables:
# Docker
docker run -e FLAPI_DB_PATH=/data/custom.db ...
# Kubernetes
env:
- name: FLAPI_DB_PATH
value: /data/custom.db
- name: PG_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
Common environment variables:
| Variable | Purpose | Example |
|---|---|---|
FLAPI_CONFIG | Override config file path | /config/flapi.yaml |
FLAPI_PORT | Override HTTP port | 8080 |
FLAPI_LOG_LEVEL | Set log verbosity | debug, info, warn |
Enterprise Cloud Platforms
Google Cloud Run
Best for: Serverless container deployment with auto-scaling to zero
# Deploy to Cloud Run
gcloud run deploy flapi \
--image ghcr.io/datazoode/flapi:latest \
--platform managed \
--region europe-west1 \
--port 8080 \
--memory 2Gi \
--cpu 1 \
--allow-unauthenticated \
--set-env-vars="FLAPI_CONFIG=/config/flapi.yaml"
Pricing: Pay per request, scales to zero
- Free tier: 2 million requests/month
- Cost: ~$0.00002400 per request (beyond free tier)
AWS App Runner
Best for: Fully managed container service with simple deployment
# Create apprunner.yaml
version: 1.0
runtime: python3
build:
commands:
image: ghcr.io/datazoode/flapi:latest
run:
runtime-version: 3.8
command: /app/flapi -c /config/flapi.yaml
network:
port: 8080
env:
- name: FLAPI_ENV
value: production
# Deploy
aws apprunner create-service \
--service-name flapi \
--source-configuration file://apprunner.yaml
Pricing: Pay for active time
- Cost: ~$0.064/vCPU-hour + $0.007/GB-hour
AWS Lambda
Best for: Sporadic traffic patterns, event-driven workloads
# Package as container image
docker build -t flapi-lambda .
# Push to ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin ACCOUNT.dkr.ecr.us-east-1.amazonaws.com
docker push ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/flapi:latest
# Create function
aws lambda create-function \
--function-name flapi \
--package-type Image \
--code ImageUri=ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/flapi:latest \
--role arn:aws:iam::ACCOUNT:role/lambda-flapi \
--memory-size 2048 \
--timeout 30 \
--environment "Variables={FLAPI_CONFIG=/config/flapi.yaml}"
Lambda containers are ephemeral. Use EFS for persistent DuckDB cache:
--file-system-config Arn=arn:aws:elasticfilesystem:REGION:ACCOUNT:access-point/ACCESS_POINT
Pricing: Pay per invocation
- Free tier: 1M requests + 400,000 GB-seconds/month
- Cost: $0.20 per 1M requests + $0.0000166667 per GB-second
Azure Container Apps
Best for: Kubernetes-based microservices without cluster management
az containerapp create \
--name flapi \
--resource-group myResourceGroup \
--image ghcr.io/datazoode/flapi:latest \
--target-port 8080 \
--ingress external \
--min-replicas 1 \
--max-replicas 10 \
--cpu 1.0 \
--memory 2.0Gi \
--env-vars FLAPI_CONFIG=/config/flapi.yaml
Pricing: Pay for vCPU and memory
- Cost: ~$0.000012/vCPU-second + $0.000002/GB-second
European Cloud Providers
IONOS Cloud
Best for: German/European data sovereignty, GDPR compliance
IONOS provides managed Kubernetes and container hosting with data centers in Germany and Spain.
# Install IONOS CLI
curl -sL https://github.com/ionos-cloud/ionosctl/releases/latest/download/ionosctl-linux-amd64.tar.gz | tar -xzv
# Create Kubernetes cluster (if not exists)
ionosctl k8s cluster create \
--name flapi-cluster \
--k8s-version 1.28 \
--datacenter-id DATACENTER_ID
# Deploy flAPI
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: flapi
labels:
app: flapi
spec:
replicas: 2
selector:
matchLabels:
app: flapi
template:
metadata:
labels:
app: flapi
spec:
containers:
- name: flapi
image: ghcr.io/datazoode/flapi:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
volumes:
- name: config
persistentVolumeClaim:
claimName: flapi-config
- name: data
persistentVolumeClaim:
claimName: flapi-data
---
apiVersion: v1
kind: Service
metadata:
name: flapi
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: flapi
EOF
Key Features:
- Data centers: Frankfurt (de/fra), Berlin (de/txl), Logroño (es/vit)
- GDPR-compliant infrastructure
- ISO 27001 certified
- German support
Pricing: Managed Kubernetes
- Cost: ~€0.10/hour per worker node + €0.01/GB storage
STACKIT
Best for: Schwarz Group ecosystem, German cloud sovereignty
# Create STACKIT Kubernetes cluster via portal or CLI
stackit kubernetes cluster create \
--project-id PROJECT_ID \
--name flapi-cluster
# Get kubeconfig
stackit kubernetes credentials get \
--cluster-id CLUSTER_ID \
--project-id PROJECT_ID
# Deploy flAPI
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: flapi
spec:
replicas: 2
selector:
matchLabels:
app: flapi
template:
metadata:
labels:
app: flapi
spec:
containers:
- name: flapi
image: ghcr.io/datazoode/flapi:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "2Gi"
cpu: "1000m"
---
apiVersion: v1
kind: Service
metadata:
name: flapi
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: flapi
EOF
Key Features:
- German data centers (operated by Schwarz Digits)
- Enterprise SLA
- Direct integration with SAP systems
- Carbon-neutral operations
Kubernetes
Generic Kubernetes Deployment
Best for: Multi-cloud portability, full control, enterprise scale
Create a complete flAPI deployment with persistent storage and horizontal scaling:
# Namespace
apiVersion: v1
kind: Namespace
metadata:
name: flapi
---
# ConfigMap for flapi.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: flapi-config
namespace: flapi
data:
flapi.yaml: |
project_name: production-api
project_description: Production flAPI deployment
template:
path: '/config/sqls'
connections:
# Your connections here
duckdb:
db_path: /data/flapi.db
access_mode: READ_WRITE
---
# PersistentVolumeClaim for DuckDB cache
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: flapi-data
namespace: flapi
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: standard
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: flapi
namespace: flapi
labels:
app: flapi
spec:
replicas: 3
selector:
matchLabels:
app: flapi
template:
metadata:
labels:
app: flapi
spec:
containers:
- name: flapi
image: ghcr.io/datazoode/flapi:latest
ports:
- containerPort: 8080
name: http
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
volumeMounts:
- name: config
mountPath: /config
- name: data
mountPath: /data
env:
- name: FLAPI_ENV
value: "production"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: config
configMap:
name: flapi-config
- name: data
persistentVolumeClaim:
claimName: flapi-data
---
# Service
apiVersion: v1
kind: Service
metadata:
name: flapi
namespace: flapi
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: flapi
---
# HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: flapi
namespace: flapi
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: flapi
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Deploy:
kubectl apply -f flapi-k8s.yaml
Ingress Configuration
For production deployments, add an Ingress with TLS:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: flapi
namespace: flapi
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.yourdomain.com
secretName: flapi-tls
rules:
- host: api.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: flapi
port:
number: 80
Indie Hacker Platforms
Fly.io
Best for: Edge deployment, global distribution, developer experience
# Install flyctl
curl -L https://fly.io/install.sh | sh
# Launch flAPI
fly launch \
--image ghcr.io/datazoode/flapi:latest \
--name flapi-app \
--region fra \
--vm-size shared-cpu-2x \
--vm-memory 2048
# Add persistent volume for cache
fly volumes create flapi_data --region fra --size 10
# Update fly.toml for volume
cat > fly.toml <<EOF
app = "flapi-app"
[build]
image = "ghcr.io/datazoode/flapi:latest"
[[mounts]]
source = "flapi_data"
destination = "/data"
[[services]]
internal_port = 8080
protocol = "tcp"
[[services.ports]]
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
EOF
# Deploy
fly deploy
Pricing: Free tier available
- Free: 3 shared-cpu-1x VMs (256MB RAM)
- Paid: ~$0.0000022/second for shared-cpu-2x (2GB RAM)
Railway
Best for: Git-based deployment, simple setup, PostgreSQL integration
# Install Railway CLI
npm i -g @railway/cli
# Login
railway login
# Initialize project
railway init
# Deploy from Docker image
railway up --image ghcr.io/datazoode/flapi:latest
# Or use railway.json for configuration
cat > railway.json <<EOF
{
"build": {
"dockerImage": "ghcr.io/datazoode/flapi:latest"
},
"deploy": {
"startCommand": "/app/flapi -c /config/flapi.yaml",
"restartPolicyType": "ON_FAILURE",
"healthcheckPath": "/health",
"healthcheckTimeout": 100
}
}
EOF
Pricing: $5 credit/month on free plan
- Free: $5/month credit (covers ~500 hours)
- Paid: $0.000231/GB-hour RAM + $0.00463/vCPU-hour
Render
Best for: Free tier for testing, managed services
# Create render.yaml
cat > render.yaml <<EOF
services:
- type: web
name: flapi
env: docker
image:
url: ghcr.io/datazoode/flapi:latest
plan: starter
healthCheckPath: /health
envVars:
- key: FLAPI_ENV
value: production
disk:
name: flapi-data
mountPath: /data
sizeGB: 10
EOF
# Deploy via Render Dashboard or CLI
render deploy
Pricing: Free tier available
- Free: 750 hours/month, sleeps after inactivity
- Starter: $7/month (persistent, no sleep)
- Standard: $25/month (2 GB RAM, 1 vCPU)
DigitalOcean App Platform
Best for: Predictable pricing, managed databases, simple scaling
# Create .do/app.yaml
mkdir -p .do
cat > .do/app.yaml <<EOF
name: flapi
services:
- name: api
image:
registry_type: GHCR
repository: datazoode/flapi
tag: latest
http_port: 8080
instance_count: 2
instance_size_slug: basic-xs
routes:
- path: /
health_check:
http_path: /health
envs:
- key: FLAPI_ENV
value: production
EOF
# Deploy via doctl
doctl apps create --spec .do/app.yaml
# Or use DigitalOcean Dashboard
Pricing: Predictable monthly cost
- Basic (512MB): $5/month
- Basic (1GB): $12/month
- Professional (2GB): $24/month
Cost-Effective VPS
Hetzner Cloud
Best for: European hosting, best price/performance ratio
# Create server via CLI
hcloud server create \
--name flapi \
--type cx21 \
--image docker-ce \
--ssh-key my-key
# SSH into server
ssh root@YOUR_SERVER_IP
# Create docker-compose.yml
cat > docker-compose.yml <<EOF
version: '3.8'
services:
flapi:
image: ghcr.io/datazoode/flapi:latest
container_name: flapi
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./config:/config:ro
- ./data:/data
- ./sqls:/sqls:ro
environment:
- FLAPI_ENV=production
deploy:
resources:
limits:
cpus: '2'
memory: 4G
reservations:
cpus: '1'
memory: 2G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Optional: Caddy for HTTPS
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
EOF
# Create Caddyfile for HTTPS
cat > Caddyfile <<EOF
api.yourdomain.com {
reverse_proxy flapi:8080
# Enable compression
encode gzip
# Security headers
header {
Strict-Transport-Security "max-age=31536000;"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}
EOF
# Start services
docker-compose up -d
# View logs
docker-compose logs -f flapi
Pricing: Excellent value
- CX11 (2GB): €4.15/month (~$4.50)
- CX21 (4GB): €5.83/month (~$6.35)
- CX31 (8GB): €10.59/month (~$11.50)
Self-Hosted
Systemd Service (Linux Binary)
For running flAPI as a native Linux service without Docker:
# Download flAPI binary
curl -L https://github.com/datazoode/flapi/releases/latest/download/flapi \
-o /usr/local/bin/flapi
chmod +x /usr/local/bin/flapi
# Create flapi user
sudo useradd -r -s /bin/false flapi
# Create directories
sudo mkdir -p /etc/flapi/{sqls,config}
sudo mkdir -p /var/lib/flapi/data
sudo chown -R flapi:flapi /etc/flapi /var/lib/flapi
# Create systemd service
sudo tee /etc/systemd/system/flapi.service > /dev/null <<EOF
[Unit]
Description=flAPI REST API Service
Documentation=https://flapi.io
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=flapi
Group=flapi
ExecStart=/usr/local/bin/flapi -c /etc/flapi/flapi.yaml
Restart=always
RestartSec=5
StartLimitInterval=0
StartLimitBurst=5
WorkingDirectory=/var/lib/flapi
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/flapi
# Resource limits
LimitNOFILE=65536
MemoryLimit=4G
[Install]
WantedBy=multi-user.target
EOF
# Copy your configuration
sudo cp flapi.yaml /etc/flapi/
sudo cp -r sqls/* /etc/flapi/sqls/
sudo chown -R flapi:flapi /etc/flapi
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable flapi
sudo systemctl start flapi
# Check status
sudo systemctl status flapi
# View logs
sudo journalctl -u flapi -f
Production Checklist
Before deploying to production, ensure you have:
Security
- Enable HTTPS/TLS (Let's Encrypt, Cloudflare, load balancer)
- Configure authentication (JWT, API keys)
- Set up rate limiting
- Whitelist environment variables in config
- Review row-level security in SQL templates
- Use secrets management (not hardcoded)
Monitoring
- Configure health check endpoint (
/health) - Set up metrics collection (Prometheus, CloudWatch)
- Configure logging (structured JSON logs)
- Set up alerting (uptime, error rates, cache hits)
- Monitor cache refresh success/failures
Performance
- Size memory for your cache needs
- Configure cache refresh schedules
- Set up horizontal scaling (HPA)
- Test under expected load
- Configure connection pooling
Backup & Recovery
- Back up DuckDB cache database
- Back up configuration files
- Document recovery procedures
- Test restore process
- Set up automated backups
High Availability
- Run multiple replicas (3+ for production)
- Use load balancer with health checks
- Configure pod/service disruption budgets
- Set up multi-region if needed
- Test failover scenarios
Troubleshooting
Port Already in Use
# Find process using port 8080
lsof -i :8080
sudo netstat -tulpn | grep 8080
# Kill process or use different port
flapi -c config.yaml --port 8081
Permission Denied (Docker)
# Run with correct user permissions
docker run --user $(id -u):$(id -g) \
-v $(pwd)/config:/config \
ghcr.io/datazoode/flapi:latest
Cache Not Persisting
# Ensure volume mount for DuckDB
-v $(pwd)/data:/data
# Check DuckDB path in config
duckdb:
db_path: /data/flapi.db # Must be on mounted volume
Memory Issues
# Increase container memory limits
docker run -m 4g ghcr.io/datazoode/flapi:latest
# Or in Kubernetes
resources:
limits:
memory: "4Gi"
Configuration Not Found
Error: flapi.yaml not found or Config file missing
# Check if config is mounted
docker exec CONTAINER_ID ls -la /config
# Should show:
# /config/flapi.yaml
# /config/sqls/
# Fix: Ensure volume mount is correct
docker run -v $(pwd)/config:/config:ro ...
# Or check ConfigMap in Kubernetes
kubectl describe configmap flapi-config -n flapi
SQL Templates Not Loading
Error: No endpoints found or Template directory empty
# Verify template path in flapi.yaml
template:
path: '/config/sqls' # Must match mounted path
# Check files exist
docker exec CONTAINER_ID ls -la /config/sqls
# Ensure YAML files have correct structure
cat config/sqls/users.yaml
# Must contain:
# url-path: /users
# sql: |
# SELECT ...
Invalid YAML Syntax
Error: YAML parse error or Invalid configuration
# Validate YAML syntax locally
yamllint config/flapi.yaml
# Common issues:
# - Incorrect indentation (use spaces, not tabs)
# - Missing quotes around special characters
# - Trailing whitespace
# Test configuration before deploying
docker run --rm \
-v $(pwd)/config:/config \
ghcr.io/datazoode/flapi:latest \
--dry-run
Connection Refused / Database Unreachable
Error: Connection refused or Host unreachable
# Inside container, host.docker.internal points to host machine
connections:
postgres:
connection_string: "postgresql://user:pass@host.docker.internal:5432/db"
# In Kubernetes, use service DNS
connections:
postgres:
connection_string: "postgresql://user:pass@postgres.default.svc.cluster.local:5432/db"
# Test connection from within container
docker exec CONTAINER_ID ping postgres-host
ConfigMap Size Limit Exceeded
Error: ConfigMap too large (> 1MB)
# Solution 1: Split into multiple ConfigMaps
kubectl create configmap flapi-sqls-users --from-file=./config/sqls/users/
kubectl create configmap flapi-sqls-products --from-file=./config/sqls/products/
# Solution 2: Use PersistentVolume instead
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: flapi-config
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Gi
# Upload config to PV manually or via init container
Read-Only Filesystem Errors
Error: Read-only file system when writing cache
# Ensure data directory is writable
docker run -v $(pwd)/data:/data ... # No :ro flag
# In Kubernetes, use ReadWriteOnce PVC for /data
volumes:
- name: data
persistentVolumeClaim:
claimName: flapi-data # Must be RWO, not RO
Environment Variable Not Working
Error: Config value not overridden by env var
# Check environment variables are set
docker exec CONTAINER_ID env | grep FLAPI
# Verify variable names match flAPI conventions
# Use UPPERCASE with underscores
FLAPI_DB_PATH=/data/custom.db # ✅ Correct
flapi-db-path=/data/custom.db # ❌ Wrong
# In Kubernetes, check pod env
kubectl describe pod flapi-xxx -n flapi | grep -A5 Environment
Cloud Storage Mount Failing
Google Cloud Run:
# Ensure service account has Storage Object Viewer role
gcloud projects add-iam-policy-binding PROJECT_ID \
--member=serviceAccount:SERVICE_ACCOUNT \
--role=roles/storage.objectViewer
# Check bucket permissions
gsutil iam get gs://YOUR_BUCKET
# Verify files are in bucket
gsutil ls gs://YOUR_BUCKET/flapi-config/
AWS Lambda (EFS):
# Check EFS mount target is in same VPC as Lambda
aws efs describe-mount-targets --file-system-id fs-xxx
# Verify Lambda has VPC permissions
# Security groups must allow NFS (port 2049)
# Check EFS access point
aws efs describe-access-points --file-system-id fs-xxx
Startup Crashes / Immediate Exit
Error: Container starts then exits immediately
# Check logs for actual error
docker logs CONTAINER_ID
kubectl logs pod/flapi-xxx -n flapi
# Common causes:
# 1. Missing config file
# 2. Invalid YAML syntax
# 3. Database connection failure
# 4. Port already in use
# Run interactively to debug
docker run -it --rm \
-v $(pwd)/config:/config \
ghcr.io/datazoode/flapi:latest \
sh
# Then manually test:
/app/flapi -c /config/flapi.yaml
Next Steps
- Configuration: Learn about flapi.yaml options
- Endpoints: Create your first API endpoints
- Caching: Optimize performance with caching
- Authentication: Secure your APIs
Need help with deployment? Check out our professional services or join the community.