# Prerequisites

This document outlines everything you need to prepare **before** running `sfp server init`. Completing these steps in advance will ensure a smooth installation.

Download the sfp CLI from [source.flxbl.io/flxbl/sfp-pro/releases](https://source.flxbl.io/flxbl/sfp-pro/releases). Install it on whichever machine will run the init command — your local workstation (remote via SSH) or the server itself (local mode).

***

## **\[1]** Server Requirements

### **\[1.a]** Hardware

| Tier            | vCPU | RAM   | Disk       | Suitable For                               |
| --------------- | ---- | ----- | ---------- | ------------------------------------------ |
| **Minimum**     | 4    | 16 GB | 100 GB SSD | Small team (< 10 developers)               |
| **Recommended** | 8    | 32 GB | 250 GB SSD | Medium team (10–50 developers)             |
| **Production**  | 16   | 64 GB | 500 GB SSD | Large team (50+), heavy parallel workflows |

> Disk should be SSD. Workflow orchestration and database queries are I/O intensive.

### **\[1.b]** Operating System

* **Linux x86\_64** (Ubuntu 22.04+ or Debian 12+ recommended)
* ARM64 (e.g., AWS Graviton) is **not supported** at this time

### **\[1.c]** Software

| Software       | Minimum Version | How to Check             |
| -------------- | --------------- | ------------------------ |
| Docker Engine  | 24.x+           | `docker --version`       |
| Docker Compose | v2.x (plugin)   | `docker compose version` |
| sfp CLI        | Latest          | `sfp --version`          |

> Docker Compose must be the v2 plugin (`docker compose`), not the legacy standalone `docker-compose`. See [Setting up Docker on the server](/flxbl/sfp-server/setting-up/setting-up-docker-on-the-server.md) for installation instructions.

***

## **\[2]** Network & DNS

### **\[2.a]** Step 1: Choose your domain

Pick a subdomain for your SFP Server. Examples:

* `flxbl.yourcompany.com`
* `codev.yourcompany.com`
* `devops.internal.yourcompany.com` (private/internal domains work too)

### **\[2.b]** Step 2: Create a DNS record

In your DNS provider (Cloudflare, Route 53, GoDaddy, etc.), create an **A record**:

| Field     | Value                                                   |
| --------- | ------------------------------------------------------- |
| **Type**  | A                                                       |
| **Name**  | `sfp` (or your chosen subdomain)                        |
| **Value** | Your server's IP address                                |
| **Proxy** | Off / DNS-only (if using Cloudflare, set to grey cloud) |
| **TTL**   | Auto or 300                                             |

### **\[2.c]** Step 3: Verify DNS resolves

```bash
dig sfp.yourcompany.com +short
# Should return your server IP
```

If using a private/internal domain, verify from a machine on the same network.

### **\[2.d]** Step 4: Choose your TLS mode

Pick a mode and gather the inputs listed below. Full configuration steps live in [Setting up sfp server → \[2\] Configure TLS](/flxbl/sfp-server/setting-up/setting-up-sfp-server.md#2-configure-tls).

| Mode                     | `--tls-mode` value     | Best for                                                          | You need ready before init                                       |
| ------------------------ | ---------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
| **Bring Your Own Cert**  | `cloudflare` (default) | Enterprise / private networks, corporate CA, Cloudflare Origin CA | `ORIGIN_CERT` + `ORIGIN_KEY` (base64-encoded PEM)                |
| **Let's Encrypt**        | `letsencrypt`          | Public-facing servers, quick evaluation                           | Ports 80 + 443 open, public DNS resolving                        |
| **Custom / On-demand**   | `custom`               | On-demand TLS via Caddy                                           | Nothing — Caddy manages certs                                    |
| **Behind Load Balancer** | `none`                 | Existing infra (ALB, F5, NGINX) terminates TLS                    | LB configured to forward port 80 with `X-Forwarded-Proto: https` |

### **\[2.e]** Firewall / Security Group

| Port     | Protocol | Purpose                                 | Required When                                |
| -------- | -------- | --------------------------------------- | -------------------------------------------- |
| **443**  | TCP      | HTTPS — main application entry point    | Always (except Option C)                     |
| **80**   | TCP      | Let's Encrypt ACME challenge            | Only for Option B (`--tls-mode letsencrypt`) |
| **8080** | TCP      | Hatchet Dashboard (workflow monitoring) | Restrict to admin IPs                        |
| **4873** | TCP      | Verdaccio (private npm registry)        | Restrict to admin/CI IPs                     |
| **3100** | TCP      | Supabase Studio (database management)   | Restrict to admin IPs                        |

> Ports 8080, 4873, and 3100 are **IP-restricted** by Caddy. To configure the allowlist, set `ALLOWED_IPS` in your `.env` file (comma-separated IPs or CIDR ranges). These ports do not need to be open to all users.

### **\[2.f]** SSH Access

The `sfp server init` command can be run **remotely** from your local machine via SSH, or **locally** on the server itself. If running remotely:

* The server must be accessible via SSH from the machine running `sfp`
* The SSH user must have permission to run `docker` commands (e.g., member of the `docker` group, or `root`)

### **\[2.g]** Outbound Access (Server)

The server requires outbound internet access for:

* Docker image pulls (GitHub Container Registry, Docker Hub) — during init and updates
* GitHub API — for OAuth authentication and repository operations at runtime

If using **Option B (`--tls-mode letsencrypt`)**, the server also needs:

* Let's Encrypt ACME (ports 80/443 outbound)

> The Supabase CLI is downloaded once during init as part of the database migration container. This happens inside Docker and requires the server to reach `github.com`.

### **\[2.h]** What you'll provide to `sfp server init`

After completing this section, you should have:

| Value                                   | Example                                          | Source |
| --------------------------------------- | ------------------------------------------------ | ------ |
| **Domain**                              | `sfp.yourcompany.com`                            | \[2.a] |
| **TLS mode**                            | `cloudflare`, `letsencrypt`, `custom`, or `none` | \[2.d] |
| **ORIGIN\_CERT** (cloudflare mode only) | Base64-encoded PEM certificate                   | \[2.d] |
| **ORIGIN\_KEY** (cloudflare mode only)  | Base64-encoded PEM private key                   | \[2.d] |

***

## **\[3]** GitHub OAuth Application

SFP uses GitHub as the authentication provider. You must create a **GitHub OAuth App** before installation.

### **\[3.a]** Steps

1. Go to **GitHub** → **Settings** → **Developer Settings** → **OAuth Apps** → **New OAuth App**
   * Direct link: <https://github.com/settings/developers>
2. Fill in the following:

   | Field                          | Value                                            |
   | ------------------------------ | ------------------------------------------------ |
   | **Application name**           | `SFP Server` (or any name you prefer)            |
   | **Homepage URL**               | `https://flxbl.yourcompany.com`                  |
   | **Authorization callback URL** | `https://flxbl.yourcompany.com/auth/v1/callback` |

   > Replace `flxbl.yourcompany.com` with your actual domain.
3. Click **Register application**
4. Note down the following credentials — you will need them during `sfp server init`:
   * **Client ID** — displayed on the app page
   * **Client Secret** — click "Generate a new client secret"

> **Important:** Store the Client Secret securely. You will not be able to view it again after navigating away.

### **\[3.b]** GitHub Enterprise Server

If you are using **GitHub Enterprise Server** (GHES) instead of github.com, the OAuth App is created at:

`https://<your-ghes-domain>/settings/developers`

The callback URL remains the same pattern: `https://flxbl.yourcompany.com/auth/v1/callback`

### **\[3.c]** Organization-Level OAuth Apps

If your GitHub organization has OAuth app restrictions enabled, an org admin may need to approve the app after creation:

1. Go to your GitHub Organization → **Settings** → **Third-party access** → **OAuth application policy**
2. Approve the `SFP Server` application

***

## **\[4]** Admin IP Addresses

Collect the public (or private, if on a corporate network) IP addresses of anyone who needs access to administrative dashboards:

* **Hatchet Dashboard** (workflow monitoring) — port 8080
* **Supabase Studio** (database management) — port 3100
* **Verdaccio** (npm registry browser) — port 4873

Set these as the `ALLOWED_IPS` value in your `.env` file after init:

* Single IPs: `ALLOWED_IPS=203.0.113.10`
* Multiple IPs: `ALLOWED_IPS=203.0.113.10,198.51.100.5`
* CIDR ranges: `ALLOWED_IPS=10.0.0.0/8,172.16.0.0/12`

> After changing `ALLOWED_IPS`, restart Caddy with `docker compose restart caddy` for the change to take effect.

***

## **\[5]** Secrets / Configuration

`sfp server init` reads required secrets from `--config-file` (recommended), environment variables, or a `--secrets-provider` (Infisical, AWS Secrets Manager). All database credentials (Postgres password, JWT secret, Supabase API keys) are **auto-generated** — you do not need to create them.

Prepare the following values in advance:

| Secret                       | Required                         | Description                                          |
| ---------------------------- | -------------------------------- | ---------------------------------------------------- |
| `GITHUB_OAUTH_CLIENT_ID`     | Yes                              | From Step 3 above                                    |
| `GITHUB_OAUTH_CLIENT_SECRET` | Yes                              | From Step 3 above                                    |
| `ORIGIN_CERT`                | If using `--tls-mode cloudflare` | Base64-encoded PEM certificate (Section 2, Option A) |
| `ORIGIN_KEY`                 | If using `--tls-mode cloudflare` | Base64-encoded PEM private key (Section 2, Option A) |
| `GITHUB_APP_ID`              | Optional                         | For GitHub App integration (repo operations)         |
| `GITHUB_APP_PRIVATE_KEY`     | Optional                         | For GitHub App integration                           |

> Place all secrets in the `secrets` block of `server.json` and pass it via `--config-file ./server.json` — this is the canonical path for repeatable / automated deployments. See [Setting up sfp server → \[1\]](/flxbl/sfp-server/setting-up/setting-up-sfp-server.md#1-create-a-serverjson-on-your-local-machine) for the file shape.

***

## **\[6]** Pre-Installation Checklist

Use this checklist to confirm readiness before running `sfp server init`:

* [ ] Server provisioned with adequate resources (see Section 1)
* [ ] Docker Engine 24+ and Docker Compose v2 installed on the server
* [ ] SSH access to the server (if running `sfp server init` remotely)
* [ ] `sfp` CLI installed on the machine that will run the init command
* [ ] Domain DNS record configured and resolving to server IP
* [ ] TLS certificate and key ready as base64-encoded PEM (if using `--tls-mode cloudflare`)
* [ ] Firewall ports open: 443 (always) + 80 (only if using `--tls-mode letsencrypt`)
* [ ] Server has outbound internet access (Docker image pulls, GitHub API)
* [ ] GitHub OAuth App created with correct callback URL
* [ ] GitHub OAuth Client ID and Client Secret noted
* [ ] Admin IP addresses collected for dashboard access (configured post-init via `ALLOWED_IPS`)

***

## Next Steps

Once all prerequisites are in place, proceed to [Setting up sfp server](/flxbl/sfp-server/setting-up/setting-up-sfp-server.md) for installation, configuration, and first-run instructions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp-server/setting-up/prerequisites.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
