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
| Variable | Description |
|---|---|
FEATHERCI_SECRET_KEY | 32-byte base64-encoded encryption key. Generate with featherci --generate-key |
FEATHERCI_BASE_URL | Public URL for OAuth callbacks and webhooks (e.g. https://ci.example.com) |
FEATHERCI_ADMINS | Comma-separated list of admin usernames |
At least one OAuth provider must also be configured (unless running in dev mode).
Optional Settings
| Variable | Default | Description |
|---|---|---|
FEATHERCI_BIND_ADDR | :8080 | Address the HTTP server binds to |
FEATHERCI_DATABASE_PATH | ./featherci.db | Path to the SQLite database file |
FEATHERCI_CACHE_PATH | ./cache | Directory for build cache storage |
FEATHERCI_WORKSPACE_PATH | ./workspaces | Directory for build workspaces (cloned repos) |
FEATHERCI_MODE | standalone | Operating 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
- Go to Settings → Developer settings → OAuth Apps → New OAuth App
- Set the authorization callback URL to
{FEATHERCI_BASE_URL}/auth/github/callback - 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.
- Go to Preferences → Applications → New Application
- Set the redirect URI to
{FEATHERCI_BASE_URL}/auth/gitlab/callback - Select the
read_userscope - 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
- Go to Site Administration → Applications → Create a new OAuth2 Application
- Set the redirect URI to
{FEATHERCI_BASE_URL}/auth/gitea/callback - 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
| Variable | Required When | Description |
|---|---|---|
FEATHERCI_MODE | Always | standalone (default), master, or worker |
FEATHERCI_WORKER_SECRET | master or worker mode | Shared secret for worker authentication |
FEATHERCI_MASTER_URL | worker mode | URL 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
- Click Projects in the navigation
- Click New Project
- Select a repository from the list (fetched from your Git provider)
- 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:
- Go to Projects → your-namespace/your-repo
- The build appears in the builds list with status running
- Click on the build to see the pipeline visualization and step logs
- 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
- Workflow Syntax Guide — Full walkthrough of all workflow features
- Migrating from Other CI — Auto-convert GitHub Actions or CircleCI configs
- Secrets — Store and use encrypted credentials
- Notifications — Get notified on build results