Skip to content
Back to skills

3016 Fly Io E5ccc7e2

ASecurity

This guide covers the complete deployment workflow for the **ContextForge** on Fly.io, including common troubleshooting steps. ---

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
devopspythonbashsqldockertestingapidatabasesecuritydocumentation

Works with

  • cli
  • api
  • mcp

Security analysis

A92/100
  • mediumUses curl or wget to download content
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 3016-fly-io_e5ccc7e2 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 3016 Fly Io E5ccc7e2?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 3016 Fly Io E5ccc7e2
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-3016-fly-io-e5ccc7e2/badge)](https://www.skillsdirectory.com/skills/tools-only-3016-fly-io-e5ccc7e2)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# ⚙️ Fly.io Deployment Guide for ContextForge

This guide covers the complete deployment workflow for the **ContextForge** on Fly.io, including common troubleshooting steps.

---

## Overview

Fly.io is a global app platform for running containers close to your users, with built-in TLS, persistent volumes, and managed Postgres support. It offers a generous free tier and automatic HTTPS with fly.dev subdomains.

---

## 1 - Prerequisites

| Requirement | Details |
| -------------------- | ------------------------------------------------------------------ |
| Fly.io account | [Sign up](https://fly.io) |
| Fly CLI | Install via Homebrew: `brew install flyctl` or see Fly docs |
| Docker **or** Podman | For local image builds (optional) |
| Containerfile | The included Containerfile with psycopg3 (psycopg[binary]) support |

---

## 2 - Quick Start (Recommended)

### 2.1 Initialize Fly project
```bash
fly launch --name your-app-name --no-deploy
```
This creates a new Fly app without deploying immediately.

### 2.2 Create and attach Fly Postgres
```bash
# Create postgres (choose Development configuration for testing)
fly postgres create --name your-app-db --region yyz

# Note the connection details from the output, you'll need the password
```

### 2.3 Set secrets
```bash
# Set authentication secrets
fly secrets set JWT_SECRET_KEY=$(openssl rand -hex 32)
fly secrets set PLATFORM_ADMIN_EMAIL=admin@example.com
fly secrets set PLATFORM_ADMIN_PASSWORD=your-secure-password
fly secrets set PLATFORM_ADMIN_FULL_NAME="Platform Administrator"

# Set database URL (CRITICAL: use postgresql+psycopg:// for psycopg3)
fly secrets set DATABASE_URL="postgresql+psycopg://postgres:YOUR_PASSWORD@your-app-db.flycast:5432/postgres"
```

**⚠️ Important:** Always use `postgresql+psycopg://` scheme for psycopg3. Do not use `postgresql://` (requires psycopg2) or `postgres://` (invalid).

### 2.4 Deploy the app
```bash
fly deploy
```

---

## 3 - Containerfile Requirements

Ensure your Containerfile explicitly installs PostgreSQL dependencies:

```dockerfile
# Create virtual environment, upgrade pip and install dependencies
RUN python3 -m venv /app/.venv && \
/app/.venv/bin/python3 -m pip install --upgrade pip setuptools pdm uv && \
/app/.venv/bin/python3 -m pip install 'psycopg[binary]' && \
/app/.venv/bin/python3 -m uv pip install ".[redis]"
```

The explicit `psycopg[binary]` (psycopg3) installation is required because uv may not properly install optional dependencies.

---

## 4 - fly.toml Configuration

Your `fly.toml` should look like this:

```toml
app = "your-app-name"
primary_region = "yyz"

[build]
dockerfile = "Containerfile"

[env]
HOST = "0.0.0.0"
PORT = "4444"

[http_service]
internal_port = 4444
force_https = true
auto_stop_machines = "stop"
auto_start_machines = true
min_machines_running = 0
processes = ["app"]

[[vm]]
memory = "1gb"
cpu_kind = "shared"
cpus = 1
```

**Note:** Don't put secrets like `DATABASE_URL` in `fly.toml` - use `fly secrets set` instead.

---

## 5 - Testing Your Deployment

### 5.1 Check app status
```bash
fly status
fly logs
```

### 5.2 Test endpoints
```bash
# Health check (no auth required)
curl https://your-app-name.fly.dev/health

# Protected endpoints (require auth)
export JWT_SECRET_KEY="same-value-you-set-in-fly-secrets"
export TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
  --username admin@example.com \
  --exp 10080 \
  --secret "$JWT_SECRET_KEY" 2>/dev/null | head -1)
curl -H "Authorization: Bearer $TOKEN" https://your-app-name.fly.dev/docs
curl -H "Authorization: Bearer $TOKEN" https://your-app-name.fly.dev/tools

# Optional: enable Basic auth for docs/API
# fly secrets set DOCS_ALLOW_BASIC_AUTH=true API_ALLOW_BASIC_AUTH=true
# curl -u admin:your-password https://your-app-name.fly.dev/docs
```

### 5.3 Expected responses
- Health: `{"status":"healthy"}`
- Protected endpoints without auth: `{"detail":"Not authenticated"}`
- Protected endpoints with auth: JSON response with data

---

## 6 - Troubleshooting

### Common Issue 1: SQLAlchemy postgres dialect error
```
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
```

**Solutions:**

1. Ensure `psycopg[binary]` is explicitly installed in Containerfile
2. Use `postgresql+psycopg://` (not `postgresql://` or `postgres://`) in DATABASE_URL
3. Rebuild with `fly deploy --no-cache`

### Common Issue 2: Database connection refused
**Solutions:**

1. Verify DATABASE_URL format: `postgresql+psycopg://postgres:PASSWORD@your-db.flycast:5432/postgres`
2. Check postgres app is running: `fly status -a your-app-db`
3. Verify password matches postgres creation output

### Common Issue 3: Machines not updating
**Solutions:**
```bash
# Force machine updates
fly machine list
fly machine update MACHINE_ID --image your-new-image

# Or restart all machines
fly scale count 0
fly scale count 1
```

---

## 7 - Production Considerations

### Security
- Change default `BASIC_AUTH_PASSWORD` to a strong password
- Consider using JWT tokens for API access
- Enable Fly's private networking for database connections

### Scaling
```bash
# Scale to multiple machines for HA
fly scale count 2

# Scale machine resources
fly scale memory 2gb
```

### Monitoring
```bash
# View real-time logs
fly logs -f

# Check machine metrics
fly machine status MACHINE_ID
```

---

## 8 - Clean Deployment Script

For a completely fresh deployment:

```bash
#!/bin/bash
set -e

APP_NAME="your-app-name"
DB_NAME="${APP_NAME}-db"
REGION="yyz"
PASSWORD=$(openssl rand -base64 32)

echo "🚀 Deploying ContextForge to Fly.io..."

# Create app
fly launch --name $APP_NAME --no-deploy --region $REGION

# Create postgres
fly postgres create --name $DB_NAME --region $REGION

# Set secrets
fly secrets set JWT_SECRET_KEY=$(openssl rand -hex 32)
fly secrets set BASIC_AUTH_USER=admin
fly secrets set BASIC_AUTH_PASSWORD=$PASSWORD

# Get postgres password and set DATABASE_URL
echo "⚠️  Set your DATABASE_URL manually with the postgres password:"
echo "fly secrets set DATABASE_URL=\"postgresql+psycopg://postgres:YOUR_PG_PASSWORD@${DB_NAME}.flycast:5432/postgres\""

# Deploy
echo "🏗️  Ready to deploy. Run: fly deploy"
```

---

## 9 - Additional Resources

- [Fly.io Documentation](https://fly.io/docs)
- [Fly Postgres Guide](https://fly.io/docs/postgres/)
- [Fly Secrets Management](https://fly.io/docs/reference/secrets/)

**Success indicators:**

- ✅ `fly status` shows machines as "started"
- ✅ `/health` endpoint returns `{"status":"healthy"}`
- ✅ Protected endpoints require authentication
- ✅ No SQLAlchemy errors in logs

Files in this skill

  • README.md848 B
  • skill.md6.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.