toreyheinz / gitblixt

public forked from gitblixt.com
Clone
e9f200e work on stuff 612 commits
README

GitBlixt

A GitLab-compatible, self-hosted Git forge built in Elixir/Phoenix. One command to install.

Features

  • GitLab API compatible — existing integrations (CodeRabbit, CI tools) work out of the box
  • Automatic HTTPS — Let's Encrypt certificates provisioned on first boot
  • SSH + HTTP — clone and push over both protocols
  • Real-time UI — Phoenix LiveView powers a fast, modern interface
  • Issues, Merge Requests, Wiki, Labels, Pipelines — full forge functionality
  • Issue Boards — kanban-style planning per repository
  • Forks and Collaboration — fork repos, manage collaborators with role-based access
  • Organizations — group repos under shared namespaces with member roles
  • Search — find repos, issues, MRs, and code across your instance
  • Releases & Milestones — tag releases and plan work with milestones
  • Code Review — blame view, file history, side-by-side diffs, draft MRs, approval rules, squash merge, auto-merge
  • Protected Branches — enforce push/merge access levels and approval requirements
  • CI/CD — GitLab CI- and GitHub Actions-compatible pipelines with runners, jobs, artifacts, and variables
  • Built-in PaaS — deploy any repo as a Docker service with managed Postgres and preview environments per merge request
  • AI Assistance — fix issues and review MRs with Claude Code running in isolated containers
  • Scheduled Agents — run recurring AI tasks on a cron schedule that open a merge request for review (never auto-merged)
  • Import — bulk-migrate repos, issues, PRs, labels, and wiki from GitHub or GitLab
  • Mirrors — push or pull mirror to/from GitHub, GitLab, or any git remote
  • Webhooks — outbound webhooks with delivery history
  • OAuth — sign in with GitHub or GitLab
  • 2FA — TOTP-based two-factor authentication
  • Personal Access Tokens — scoped tokens for the API and git over HTTPS
  • Snippets — share standalone code snippets (public, internal, or private)
  • Notifications — in-app notification center with unread badge
  • Activity Feeds — see recent actions on your dashboard and per-project
  • Explore — discover public repositories on your instance
  • Admin Panel — user management, settings, migrations, app overview, log streaming, remote shell
  • Backups — scheduled and on-demand backups (database, repos, uploads) to local disk or S3

Quick Start

Install Docker Engine and the Compose plugin (docker-ce and docker-compose-plugin) if you haven't already — see Docker's install docs.

curl -fsSL https://gitblixt.com/install.sh | GITBLIXT_HOST=git.yourdomain.com sh

That's it. The installer creates the config, downloads the compose file, and starts GitBlixt.

Open https://git.yourdomain.com — the first registered user becomes admin.

Manual Install

If you prefer to set things up yourself:

mkdir gitblixt && cd gitblixt

# Generate config
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 32)
GITBLIXT_HOST=git.yourdomain.com
DATA_DIR=./data
EOF

# Download compose file and Caddyfile
curl -fsSL https://gitblixt.com/docker-compose.yml -o docker-compose.yml
mkdir -p caddy
curl -fsSL https://gitblixt.com/Caddyfile -o caddy/Caddyfile

# Edit caddy/Caddyfile — replace gitblixt.example.com with your domain
nano caddy/Caddyfile

# Create overlay networks (required for Swarm + PaaS)
docker swarm init 2>/dev/null || true
docker network create --driver overlay --attachable gitblixt 2>/dev/null || true
docker network create --driver overlay --attachable proxy 2>/dev/null || true

# Start
docker compose up -d

Caddy and PaaS

GitBlixt uses Caddy as a reverse proxy for both itself and any apps you deploy via the built-in PaaS. The Caddyfile must include admin 0.0.0.0:2019 in the global options block so GitBlixt can manage routes via Caddy's admin API over the Docker overlay network.

The caddy and gitblixt services must both be on the proxy overlay network so GitBlixt can reach Caddy at http://caddy:2019. The gitblixt network is used for Postgres connectivity.

When you enable deployment for a repository, GitBlixt will automatically register Caddy routes for the app's domains. Caddy handles TLS certificate provisioning via Let's Encrypt.

Requirements

  • Standard rootful Docker with the Compose plugin. GitBlixt drives the host Docker (CI, PaaS deploys, AI jobs) and runs as a Swarm service, so the daemon must not use userns-remap or rootless mode, and must not have live-restore enabled (it's incompatible with Swarm mode). Some cloud images ship these on — symptoms are permission denied … docker.sock in CI, a swarm init failure, or /data files owned by uid 100000. See Troubleshooting.
  • A domain pointing at your server
  • Ports 80, 443, and 22 open

Configuration

All configuration is via environment variables in your .env file (next to docker-compose.yml).

Variable Default Description
GITBLIXT_HOST localhost Your domain name
POSTGRES_PASSWORD required Database password
DATA_DIR ./data Host path for persistent data
SSL_MODE auto off (installer default — Caddy terminates SSL), auto (app gets its own cert, standalone only), or manual
SMTP_HOST — SMTP server hostname (e.g. email-smtp.us-west-2.amazonaws.com)
SMTP_PORT 587 SMTP port
SMTP_USERNAME — SMTP username
SMTP_PASSWORD — SMTP password
GITBLIXT_FROM_EMAIL — Sender address for outgoing emails

A secret key is auto-generated and persisted to data/config/secret_key_base on first boot.

External Database

To use an existing Postgres instead of the compose-managed one, set DATABASE_URL in the gitblixt service environment and remove the postgres service from your compose file:

environment:
  DATABASE_URL: ecto://user:pass@your-db-host:5432/gitblixt

Minimum Postgres version: 14.

SSL Modes

Mode Description
auto (default) Automatic HTTPS via Let's Encrypt
manual Provide your own cert at data/ssl/cert.pem and data/ssl/key.pem
off HTTP only (for behind-a-proxy setups like Cloudflare or nginx)

Behind Cloudflare

If using Cloudflare as a reverse proxy, set SSL_MODE=off and configure Cloudflare's SSL mode to Full or Flexible.

Data & Volumes

All persistent data lives under your DATA_DIR (default ./data):

data/
  postgres/     # PostgreSQL data directory
  repos/        # Bare git repositories
  uploads/      # Avatars and file uploads
  ssl/          # SSL certificates
  ssh/          # SSH host keys
  config/       # Auto-generated config (secret key)

Upgrading

docker service update --image willc0de4food/gitblixt:latest gitblixt

Swarm performs a zero-downtime rolling update (start-first). Migrations run automatically on startup. Your data persists across upgrades.

New installs run Postgres 18. Minor updates within the same major are safe (docker compose pull && docker compose up -d). A major upgrade (e.g. 16 → 18) is not — Postgres won't start on a data directory from an older major, so existing installs must dump-and-restore across the bump. Full procedure: Upgrading → Postgres major version.

Backup and Restore

Configure scheduled backups (local or S3) and trigger on-demand ones under Admin → Backups. Enable encryption there too — GitBlixt shows the private key once; save it off-server. With encryption on, each backup is two objects (*.tar.gz.enc + *.key.enc) and you need both plus the private key to restore.

The app runs as a Swarm service named gitblixt (only Postgres and Caddy are Compose-managed), so run bin/gitblixt commands via docker exec $(docker ps -q -f name=gitblixt.1) bin/gitblixt …, not docker compose exec.

Restoring has real footguns — the private key must be PEM (not OpenSSH), you must restore into an empty database, and the encryption key (secret_key_base / APP_SECRETS_KEY) has to carry over or encrypted columns won't decrypt. The full, tested procedure is in the docs:

Troubleshooting

SSL not working: Check that port 80 is open (needed for ACME HTTP-01 challenges). Try SSL_MODE=off to verify the app works over HTTP first.

SSH not working: Ensure port 22 is not in use by another SSH server on the host.

Container won't start: Check docker service logs gitblixt for startup errors.

CI/deploys fail with permission denied … docker.sock (or /data owned by uid 100000): the daemon is using userns-remap or rootless mode. GitBlixt needs rootful Docker — see Troubleshooting → docker.sock.

docker swarm init fails / "not a swarm manager": live-restore is incompatible with Swarm — set "live-restore": false in /etc/docker/daemon.json, restart Docker, then docker swarm init.

git push warns "REMOTE HOST IDENTIFICATION HAS CHANGED" after a migration: expected (host keys aren't in the backup). Run ssh-keygen -R your-host and accept the new key.

Cloudflare error 526: origin has no valid cert yet — see SSL & HTTPS.

Email not sending: See the Email (SMTP) section below.

More install, restore, and migration gotchas — and their fixes — are documented at /docs/troubleshooting.

Email (SMTP)

Email is used for login links, password resets, admin-created user invitations, and notifications.

There are two ways to configure SMTP — environment variables or the Admin UI. Admin UI (database) settings take priority over environment variables.

Option 1: Environment Variables

Add these to your .env file:

SMTP_HOST=email-smtp.us-west-2.amazonaws.com
SMTP_PORT=587
SMTP_USERNAME=AKIA...
SMTP_PASSWORD=...
GITBLIXT_FROM_EMAIL=noreply@yourdomain.com

Then add them to the gitblixt service's environment: section in your compose file, or restart with docker compose up -d.

Option 2: Admin UI

Go to Admin > Settings and fill in the SMTP section. All fields are stored in the database and override any environment variables.

Required Fields

Field Required Notes
SMTP Host Yes Your SMTP provider's hostname
Port Yes Usually 587 (STARTTLS) or 465 (implicit TLS)
Username Yes SMTP auth username
Password Yes SMTP auth password
From Email Yes Must be a verified sender identity with your provider
TLS No if_available (default), always, or never

The From Email is the address that appears in the "From" field of all outgoing emails. Your SMTP provider must allow sending from this address — for example, AWS SES requires the domain or email to be verified as a sending identity.

AWS SES

  1. Use the SES SMTP endpoint for your region (e.g. email-smtp.us-west-2.amazonaws.com)
  2. Create SMTP credentials in the SES console — these are separate from regular IAM access keys
  3. Verify your sending domain (or individual email) in the SES console
  4. Set the From Email to an address on your verified domain (e.g. noreply@yourdomain.com)
  5. If your SES account is in sandbox mode, you can only send to verified recipient addresses — request production access to send to anyone

Troubleshooting Email

  • Use the Send Test button in Admin > Settings to verify your configuration
  • Check docker compose logs gitblixt for delivery errors
  • retries_exceeded / TLS errors: Your SMTP provider requires TLS but the handshake is failing. Ensure the host and port are correct and try setting TLS to always
  • No errors but email not received: Check that the From Email is set and is a verified sender identity. Without a From Email, emails silently fail

Development

Prerequisites

  • Elixir 1.18+ / OTP 27+
  • PostgreSQL 16+
  • Node.js (for asset building)
  • Git

Setup

git clone https://gitblixt.com/gitblixt/gitblixt.git
cd gitblixt
mix setup        # Install deps, create DB, run migrations, build assets
mix phx.server   # Start dev server at localhost:4000

Commands

Command Purpose
mix setup Install deps, create DB, run migrations, build assets
mix phx.server Start dev server (localhost:4000)
iex -S mix phx.server Start dev server with interactive shell
mix test Run all tests
mix test path/to/test.exs:42 Run a specific test by line
mix format Format all code
mix precommit Run before committing (compile, format, test)

Architecture

  • Elixir/Phoenix 1.8 with Bandit HTTP server
  • PostgreSQL 16 via Ecto (Docker Compose in production, local in dev)
  • Docker Swarm for zero-downtime app deploys (start-first rolling updates)
  • Phoenix LiveView for real-time UI
  • Tailwind CSS 4 + daisyUI for styling
  • Oban for background jobs (mirror sync, CI dispatch, webhook delivery, deployments, AI jobs, backups, imports)
  • Git operations abstracted behind a behaviour (Gitblixt.Git) with shell (Gitblixt.Git.Shell) and native Rust/gitoxide (Gitblixt.Git.Native) implementations
  • SSH transport via the Erlang :ssh application with database-backed key lookup

Building the Docker Image

docker build -t willc0de4food/gitblixt:latest .

Documentation

A complete, in-app knowledgebase ships with every instance at /docs — covering installation, configuration, and every feature (repositories, issues, merge requests, code review, CI/CD, the built-in PaaS, the AI assistant, and more).

GitBlixt also exposes a GitLab-compatible REST API at /api/v4, so existing GitLab tooling works against your instance unchanged. The endpoint reference lives at /docs/api.

Public repositories can be cloned by anyone over HTTPS — no account required:

git clone https://your-instance.example/namespace/repo.git

Pushing, and cloning private repositories, requires authentication: an SSH key or a personal access token (see /docs/access-tokens).

Contributing

Contributions are welcome — see CONTRIBUTING.md for the workflow and DCO sign-off requirement.

License

GitBlixt is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

If you run a modified version of GitBlixt as a network service, AGPL-3.0 requires that you make the corresponding source available to your users.

Copyright (c) 2026 GitBlixt contributors.

Disclaimer

GitBlixt is provided "as is", without warranty of any kind and you use it at your own risk. To the fullest extent permitted by law, the authors and contributors are not liable for any damage, data loss, downtime, security incident, cost, or other harm arising from the use, deployment, or operation of this software — including anything that happens to your server, infrastructure, or data. You are solely responsible for how you deploy and operate it. The full legal terms are in sections 15–17 of the LICENSE.