Getting Started

Installation

Docker (Recommended)

The fastest way to run FeatherCI. The Docker socket mount is required so FeatherCI can run build steps in containers.

docker run -d \
  -p 8080:8080 \
  -v featherci-data:/data \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e FEATHERCI_SECRET_KEY=$(openssl rand -base64 32) \
  -e FEATHERCI_BASE_URL=http://localhost:8080 \
  -e FEATHERCI_ADMINS=yourusername \
  -e FEATHERCI_GITHUB_CLIENT_ID=your_client_id \
  -e FEATHERCI_GITHUB_CLIENT_SECRET=your_client_secret \
  ghcr.io/featherci/featherci:latest

See Docker Deployment for production configuration, Docker Compose, and the sibling container pattern.

Homebrew (macOS / Linux)

brew install featherci/tap/featherci

Create a config file and start the service:

# Generate an encryption key
featherci --generate-key

# Create config file
mkdir -p $(brew --prefix)/etc/featherci
cp $(brew --prefix)/share/featherci/config.yaml.example \
   $(brew --prefix)/etc/featherci/config.yaml

# Edit with your settings (secret key, OAuth credentials, admins)
$EDITOR $(brew --prefix)/etc/featherci/config.yaml

# Start as a background service
brew services start featherci

Logs are written to $(brew --prefix)/var/log/featherci/. Data is stored in $(brew --prefix)/var/featherci/.

Binary Download

Download a pre-built binary from the GitHub releases page:

# Download the latest release (example for Linux amd64)
curl -Lo featherci https://github.com/featherci/featherci/releases/latest/download/featherci-linux-amd64
chmod +x featherci

# Generate an encryption key
./featherci --generate-key
# Copy the output and set it as FEATHERCI_SECRET_KEY

# Run it
./featherci

From Source

Requires Go 1.22+ and Make:

git clone https://github.com/featherci/featherci.git
cd featherci
make build
./bin/featherci

Development Mode

For local development without OAuth configuration:

make dev

This starts FeatherCI with the --dev flag, which skips OAuth and auto-logs in as an admin user.

Verify Installation

curl http://localhost:8080/health
# {"status":"ok"}

curl http://localhost:8080/ready
# {"status":"ready"}

Then open http://localhost:8080 in your browser.


Configuration

FeatherCI can be configured with a YAML config file, environment variables, or a .env file. Precedence (highest to lowest): environment variables > .env file > YAML config file > defaults.

The config file is automatically loaded from /etc/featherci/config.yaml or ./config.yaml. You can specify a custom path with featherci --config /path/to/config.yaml or the FEATHERCI_CONFIG environment variable.

Required Settings

VariableDescription
FEATHERCI_SECRET_KEY32-byte base64-encoded encryption key. Generate with featherci --generate-key
FEATHERCI_BASE_URLPublic URL for OAuth callbacks and webhooks (e.g. https://ci.example.com)
FEATHERCI_ADMINSComma-separated list of admin usernames

At least one OAuth provider must also be configured (unless running in dev mode).

Optional Settings

VariableDefaultDescription
FEATHERCI_BIND_ADDR:8080Address the HTTP server binds to
FEATHERCI_DATABASE_PATH./featherci.dbPath to the SQLite database file
FEATHERCI_CACHE_PATH./cacheDirectory for build cache storage
FEATHERCI_WORKSPACE_PATH./workspacesDirectory for build workspaces (cloned repos)
FEATHERCI_MODEstandaloneOperating mode: standalone, master, or worker

OAuth Providers

Configure at least one OAuth provider. For each provider, create an OAuth application with the callback URL:

{FEATHERCI_BASE_URL}/auth/{provider}/callback

For example: https://ci.example.com/auth/github/callback

GitHub

  1. Go to Settings → Developer settings → OAuth Apps → New OAuth App
  2. Set the authorization callback URL to {FEATHERCI_BASE_URL}/auth/github/callback
  3. Copy the Client ID and Client Secret
FEATHERCI_GITHUB_CLIENT_ID=your_client_id
FEATHERCI_GITHUB_CLIENT_SECRET=your_client_secret

GitLab

Works with gitlab.com or self-hosted GitLab instances.

  1. Go to Preferences → Applications → New Application
  2. Set the redirect URI to {FEATHERCI_BASE_URL}/auth/gitlab/callback
  3. Select the read_user scope
  4. Copy the Application ID and Secret
FEATHERCI_GITLAB_URL=https://gitlab.com          # or your self-hosted URL
FEATHERCI_GITLAB_CLIENT_ID=your_application_id
FEATHERCI_GITLAB_CLIENT_SECRET=your_secret

Gitea / Forgejo

  1. Go to Site Administration → Applications → Create a new OAuth2 Application
  2. Set the redirect URI to {FEATHERCI_BASE_URL}/auth/gitea/callback
  3. Copy the Client ID and Client Secret
FEATHERCI_GITEA_URL=https://your-gitea-instance.com
FEATHERCI_GITEA_CLIENT_ID=your_client_id
FEATHERCI_GITEA_CLIENT_SECRET=your_client_secret

Note: Gitea URL is required when Gitea/Forgejo OAuth is configured. There is no default.

Distributed Mode

VariableRequired WhenDescription
FEATHERCI_MODEAlwaysstandalone (default), master, or worker
FEATHERCI_WORKER_SECRETmaster or worker modeShared secret for worker authentication
FEATHERCI_MASTER_URLworker modeURL of the master instance

Your First Project

1. Log In

Open FeatherCI in your browser and sign in with your configured OAuth provider. The first user listed in FEATHERCI_ADMINS is automatically an admin.

2. Add a Project

  1. Click Projects in the navigation
  2. Click New Project
  3. Select a repository from the list (fetched from your Git provider)
  4. Click Create

FeatherCI automatically registers a webhook on the repository so it receives push and pull request events.

3. Create a Workflow File

In your repository, create .featherci/workflow.yml:

name: My First Build

on:
  push:
    branches: [main]
  pull_request:

steps:
  - name: hello
    image: alpine:latest
    commands:
      - echo "Hello from FeatherCI!"
      - echo "Branch: $FEATHERCI_BRANCH"
      - echo "Commit: $FEATHERCI_COMMIT"

Commit and push this file to your repository.

4. See Your Build

After pushing, FeatherCI receives the webhook event and starts a build:

  1. Go to Projects → your-namespace/your-repo
  2. The build appears in the builds list with status running
  3. Click on the build to see the pipeline visualization and step logs
  4. Logs stream in real-time as the step executes

5. Expand Your Workflow

name: CI Pipeline

on:
  push:
  pull_request:

steps:
  - name: test
    image: golang:1.22
    commands:
      - go test ./...

  - name: lint
    image: golang:1.22
    commands:
      - golangci-lint run

  - name: build
    image: golang:1.22
    depends_on: [test, lint]
    commands:
      - go build -o app ./cmd/app

test and lint run in parallel. build waits for both to succeed.

Next Steps