Files

6.2 KiB

Fly.io Deployment

OpenConnector can run on Fly.io as the Node Docker runtime. The repository defaults to persistent SQLite storage; external PostgreSQL and S3-compatible transit storage are available for multi-machine deployments. Fly provides TLS termination, remote Docker builds, health checks, rolling deploys, and optional custom domains.

This deployment uses the repository's docker/Dockerfile, the Fly app config in fly.toml, and a Fly volume mounted at /app/data.

Prerequisites

  • A Fly.io account.
  • flyctl installed and authenticated with fly auth login.
  • Docker available locally, or Fly remote builders enabled.
  • A public origin for OAuth callback URLs, such as https://api.example.com or the default https://<app>.fly.dev hostname.

Create The App

Create a Fly app without deploying yet:

fly apps create my-open-connector

Fly app names are globally unique. If you choose a different name, update the app field in fly.toml before deploying:

app = "my-open-connector"

Create Persistent Storage

The Docker image stores runtime data in /app/data. Create a Fly volume with the same source name as fly.toml:

fly volumes create open_connector_data \
  --region iad \
  --size 1 \
  --app my-open-connector

Increase --size if you expect large run logs, many stored credentials, or heavy temporary file transit usage.

Set Secrets

Store production secrets with Fly instead of committing them to fly.toml:

OOMOL_CONNECT_ENCRYPTION_KEY=$(openssl rand -base64 32)
OOMOL_CONNECT_ADMIN_TOKEN=$(openssl rand -base64 32)
OOMOL_CONNECT_RUNTIME_TOKEN=$(openssl rand -base64 32)

fly secrets set \
  OOMOL_CONNECT_ORIGIN="https://my-open-connector.fly.dev" \
  OOMOL_CONNECT_ENCRYPTION_KEY="$OOMOL_CONNECT_ENCRYPTION_KEY" \
  OOMOL_CONNECT_ADMIN_TOKEN="$OOMOL_CONNECT_ADMIN_TOKEN" \
  OOMOL_CONNECT_RUNTIME_TOKEN="$OOMOL_CONNECT_RUNTIME_TOKEN" \
  --app my-open-connector

Keep OOMOL_CONNECT_ENCRYPTION_KEY in a password manager or another external secrets vault. If the key is lost, encrypted credentials, OAuth client configuration, and completed idempotent Action responses in the runtime database cannot be recovered.

Optional runtime policy can also be set as secrets:

fly secrets set \
  OOMOL_CONNECT_ALLOWED_ACTIONS="github.*,hackernews.*" \
  OOMOL_CONNECT_ALLOWED_PROXIES="github" \
  --app my-open-connector

See configuration.md for the full environment variable reference.

Deploy

Deploy from the repository root:

fly deploy --config fly.toml --remote-only

The Fly config uses:

  • docker/Dockerfile for the image build.
  • internal_port = 3000 for the Node runtime.
  • /health for HTTP health checks.
  • /app/data as the mounted persistent data directory.

PostgreSQL And Multiple Machines

To use external PostgreSQL, set OOMOL_CONNECT_DATABASE_URL as a Fly secret. PostgreSQL migrations are never applied by application startup, so run them from a trusted deployment environment before the first deploy and before deploying a version with new migrations:

OOMOL_CONNECT_DATABASE_URL="postgresql://migrator:[email protected]/open_connector?sslmode=verify-full" \
npm run runtime:migrate

fly secrets set \
  OOMOL_CONNECT_DATABASE_URL="postgresql://app:[email protected]/open_connector?sslmode=verify-full" \
  --app my-open-connector

The migration and application URLs may use separate PostgreSQL roles. Application instances only check migration readiness and refuse to start when a required migration is missing.

Multiple machines also need shared transit-file storage. Configure the S3 backend and the same bucket, endpoint, credentials, and OOMOL_CONNECT_ENCRYPTION_KEY on every machine. See configuration.md for the required settings.

The default fly.toml mount exists for SQLite. For a PostgreSQL and S3 deployment, remove the [mounts] section from the deployment config so Fly does not require a per-machine volume. The container filesystem still provides temporary upload staging, but no runtime state depends on that filesystem. Size OOMOL_CONNECT_DATABASE_POOL_MAX so the combined pools of all machines leave database capacity for migrations and administration.

Verify The Runtime

Check the health endpoint:

curl https://my-open-connector.fly.dev/health

The expected response is:

{ "ok": true }

View logs when diagnosing deployment or startup issues:

fly logs --app my-open-connector

Configure OAuth Redirects

For OAuth2 providers, set OOMOL_CONNECT_ORIGIN to the public origin users will access. The runtime builds provider callback URLs from that origin and /oauth/callback.

For example, with:

OOMOL_CONNECT_ORIGIN="https://api.example.com"

the OAuth callback URL is:

https://api.example.com/oauth/callback

Add that exact callback URL to each provider OAuth app.

Custom Domain

Register the domain with Fly:

fly certs add api.example.com --app my-open-connector

Fly prints the DNS records to create. After DNS is ready, update the public origin:

fly secrets set \
  OOMOL_CONNECT_ORIGIN="https://api.example.com" \
  --app my-open-connector

Check certificate status:

fly certs check api.example.com --app my-open-connector

Updating

For SQLite, deploy new versions from the repository root:

git pull
fly deploy --config fly.toml --remote-only

The mounted volume keeps connect.sqlite and transit files across deployments.

For PostgreSQL, run npm run runtime:migrate with the migration database URL before fly deploy.

Scaling

fly.toml defaults to suspending the single machine when idle:

[http_service]
min_machines_running = 0

For production traffic that should avoid cold starts, keep one machine running:

[http_service]
min_machines_running = 1

Keep the machine count at one for the default SQLite deployment. Fly volumes are attached to individual machines, so horizontal scaling requires PostgreSQL and shared S3-compatible transit storage as described above. For the default Fly setup, prefer increasing the VM size before adding more machines.