Self-hosting

Run Fettlecode on your own server

Fettlecode is one server, a PostgreSQL database and a folder of plain Git repositories. This page says what it needs, how sign-in and Git are set up, and every setting it reads.

Not released yet. Fettlecode is in development. Its source code isn't public, and the Docker image and Compose file are part of the work for 1.0, so there's nothing to install today. The settings below are the ones the server reads now; they may still change before the first release.

What it needs

Installing it

The plan for 1.0 is a published Docker image and a Compose file, with backups and full docs. These are the steps we're planning; they'll be confirmed when it's released:

  1. Install Docker with Compose v2: Docker Desktop on Windows and macOS, or Docker Engine on Linux.
  2. In the Fettlecode folder, start it:
docker compose up -d

Then open it and create your account. The first person to sign up becomes the instance admin, and sign-up closes behind them: everyone else needs an invitation or single sign-on, unless you set ALLOW_SIGNUP=true.

Running it for a team

Fettlecode reads its settings from the environment. A minimal set:

# The address people use. No trailing slash.
APP_URL=https://code.example.com

# PostgreSQL, and where repositories are kept
DATABASE_URL=postgres://fettlecode:<password>@db:5432/fettlecode
DATA_DIR=/var/lib/fettlecode

# Signs sessions. At least 32 characters.
AUTH_SECRET=<openssl rand -hex 32>

# Behind a reverse proxy, so client addresses are right
TRUST_PROXY=true

# Email: invitations and notifications
SMTP_URL=smtps://user:password@smtp.example.com:465
MAIL_FROM=Fettlecode <code@example.com>

Fettlecode checks every setting when it starts. If one is wrong or missing, it stops and names it, rather than half-working, and it never prints a secret's value.

With no mail server, nothing breaks: organisation owners copy an invitation link and send it themselves.

Git over HTTPS and SSH

Clone, fetch and push over HTTPS with a personal access token as the password, or over SSH with a key added in Settings. SSH listens on port 2222 by default; set SSH_PORT to change it, or to 0 to turn it off.

# Clone over HTTPS or SSH
git clone https://code.example.com/acme/api.git
git clone ssh://git@code.example.com:2222/acme/api.git

# The hook that adds a Change-Id to each commit
curl -o .git/hooks/commit-msg https://code.example.com/tools/commit-msg
chmod +x .git/hooks/commit-msg

Git LFS uses the same address and token. LFS_MAX_OBJECT_MB caps a single file, at 2,048 MB by default.

Single sign-on

All of these are in every copy. Use as many as you need.

OpenID Connect

Register Fettlecode with your provider using the redirect address <APP_URL>/api/auth/callback/<id>, then set:

OIDC_ID=keycloak
OIDC_NAME=Keycloak
OIDC_ISSUER=https://sso.example.com/realms/acme
OIDC_CLIENT_ID=fettlecode
OIDC_CLIENT_SECRET=...

For several providers, set OIDC_PROVIDERS to a JSON list of {id, name, issuer, clientId, clientSecret}. People who arrive through OIDC for the first time get an account, unless you set OIDC_ALLOW_SIGNUP=false.

SAML

Give your identity provider (Okta, Entra ID, Google Workspace, ADFS and others) this address: <APP_URL>/api/auth/sso/saml2/sp/metadata?providerId=saml. Then point Fettlecode at the identity provider's metadata file:

SAML_IDP_METADATA=/etc/fettlecode/idp-metadata.xml
SAML_NAME=Acme sign-in
# Existing accounts with these email domains may sign in through SAML
SAML_DOMAIN=example.com

Instead of a metadata file, you can set SAML_ENTRY_POINT, SAML_IDP_ENTITY_ID and SAML_IDP_CERT together.

LDAP

Directory sign-in works with Active Directory, OpenLDAP and others. Setting LDAP_URL and LDAP_BASE_DN turns it on:

LDAP_URL=ldaps://directory.example.com
LDAP_BASE_DN=dc=example,dc=com
LDAP_BIND_DN=cn=fettlecode,ou=services,dc=example,dc=com
LDAP_BIND_PASSWORD=...

SCIM provisioning

Each organisation's owners make a SCIM token in Settings, under Provisioning, and give your identity provider the address <APP_URL>/scim/v2. It then adds, updates and deactivates members, and keeps teams in step with its groups.

Connecting GitHub

Importing from GitHub needs no settings. Two other parts do, and both work with GitHub Enterprise Server too, through GITHUB_URL and GITHUB_API_URL.

Where your data lives

Backup and restore scripts, and a JSON export of reviews and comments, are planned. Until they arrive, back up the data folder and the database together.

All settings

Setting Default What it does
APP_URL Required The address people use to reach Fettlecode, with no trailing slash
DATABASE_URL Required The PostgreSQL connection string
AUTH_SECRET Required Signs sessions. 32 characters or more
DATA_DIR ./data Where repositories, Git LFS files and the SSH host key are kept
PORT, HOST 3200, 0.0.0.0 Where the server listens
TRUST_PROXY false Trust the reverse proxy's forwarded client address
ALLOW_SIGNUP false Let anyone create an account
LOG_LEVEL info From fatal to trace
MAX_CHANGES_PER_PUSH 50 The most commits one push for review may turn into changes (up to 500)
LFS_MAX_OBJECT_MB 2048 The largest single file Git LFS may store
SSH_PORT, SSH_HOST 2222, APP_URL's host Git over SSH, and the host shown in SSH clone addresses. Port 0 turns it off
SMTP_URL, MAIL_FROM Off Outgoing email, as smtp:// or smtps://
INTEGRATIONS_ALLOW_PRIVATE true Let repositories connect Fettleboard or Fettledesk on a private address. Set it to false on a shared host
OIDC_ID, OIDC_NAME, OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET Off One OpenID Connect provider
OIDC_PROVIDERS Off Several OpenID Connect providers, as a JSON list
OIDC_ALLOW_SIGNUP true People arriving through OIDC for the first time get an account
LDAP_URL, LDAP_BASE_DN Off Turn on directory sign-in
LDAP_BIND_DN, LDAP_BIND_PASSWORD None The account Fettlecode searches the directory with
LDAP_USER_FILTER uid, sAMAccountName or mail How a username is found, with {username} in the filter
LDAP_NAME, LDAP_NAME_ATTR, LDAP_MAIL_ATTR Directory, displayName, mail The name on the sign-in page, and which attributes hold the name and email
LDAP_ALLOW_SIGNUP, LDAP_VERIFY_TLS true, true Create accounts on first sign-in; check the directory's certificate
SAML_IDP_METADATA Off The path to the identity provider's metadata file
SAML_ENTRY_POINT, SAML_IDP_ENTITY_ID, SAML_IDP_CERT Off The identity provider, set by hand instead of a metadata file
SAML_NAME, SAML_DOMAIN Single sign-on, none The name on the sign-in page; email domains whose existing accounts SAML may sign in to
SAML_EMAIL_ATTR, SAML_NAME_ATTR email, displayName Which attributes hold the email and name
SAML_ALLOW_SIGNUP, SAML_WANT_ASSERTIONS_SIGNED true, false Create accounts on first sign-in; require signed assertions
GITHUB_URL, GITHUB_API_URL github.com, api.github.com Where GitHub is; change both for GitHub Enterprise Server
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET Off Sign in with GitHub, through a GitHub OAuth app
GITHUB_ALLOWED_ORGS, GITHUB_ALLOW_SIGNUP None, false Who may create an account by signing in with GitHub
GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET Off A GitHub App for the pull request bridge. The key is a PEM, or a path to one