Forgejo Git Hosting Installation
Forgejo is a community-driven, lightweight self-hosted Git platform forked from Gitea, with a focus on openness and federation. This guide covers installing Forgejo on Linux via Docker, setting up Forgejo Actions CI/CD, federation support, and migrating from Gitea.
Prerequisites
- Ubuntu 20.04+/Debian 11+ or CentOS 8+/Rocky Linux 8+
- Docker and Docker Compose (for Docker install)
- A domain name with DNS configured
- 512 MB RAM minimum (1 GB+ recommended)
- Root or sudo access
Installing Forgejo with Docker
Docker is the recommended method for easy updates:
mkdir -p /opt/forgejo/{data,config}
cat > /opt/forgejo/docker-compose.yml << 'EOF'
version: '3.8'
services:
forgejo:
image: codeberg.org/forgejo/forgejo:7
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- FORGEJO__database__PASSWD=forgejo_password
volumes:
- ./data:/data
ports:
- "3000:3000"
- "2222:22"
depends_on:
- db
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
- POSTGRES_DB=forgejo
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=forgejo_password
volumes:
- ./postgres:/var/lib/postgresql/data
restart: unless-stopped
EOF
cd /opt/forgejo
docker compose up -d
docker compose logs -f forgejo
Binary Installation
For a non-Docker setup:
# Create a dedicated user
sudo adduser --system --no-create-home --group forgejo
sudo mkdir -p /var/lib/forgejo /etc/forgejo
sudo chown forgejo:forgejo /var/lib/forgejo
sudo chmod 750 /var/lib/forgejo
# Download the latest binary from Codeberg
VERSION=$(curl -s https://codeberg.org/api/v1/repos/forgejo/forgejo/releases \
| python3 -c "import sys,json; releases=json.load(sys.stdin); print(releases[0]['tag_name'])")
wget "https://codeberg.org/forgejo/forgejo/releases/download/${VERSION}/forgejo-${VERSION#v}-linux-amd64" \
-O /usr/local/bin/forgejo
chmod +x /usr/local/bin/forgejo
# Create systemd service
sudo tee /etc/systemd/system/forgejo.service << 'EOF'
[Unit]
Description=Forgejo
After=network.target postgresql.service
[Service]
Type=simple
User=forgejo
Group=forgejo
WorkingDirectory=/var/lib/forgejo/
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=on-failure
Environment=USER=forgejo HOME=/var/lib/forgejo FORGEJO_WORK_DIR=/var/lib/forgejo
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now forgejo
Initial Setup
Navigate to http://your-server:3000 for the web installer.
Key settings to configure:
- Database: PostgreSQL (recommended) or SQLite for small instances
- Site URL: Must match your actual domain for clone URLs to work
- Administrator account: Create the first admin user
Or configure via app.ini before first run:
sudo tee /etc/forgejo/app.ini << 'EOF'
APP_NAME = My Forgejo Instance
RUN_MODE = prod
RUN_USER = forgejo
[server]
DOMAIN = git.yourdomain.com
HTTP_PORT = 3000
ROOT_URL = https://git.yourdomain.com/
SSH_DOMAIN = git.yourdomain.com
START_SSH_SERVER = false
[database]
DB_TYPE = postgres
HOST = 127.0.0.1:5432
NAME = forgejo
USER = forgejo
PASSWD = forgejo_password
EOF
Set up Nginx reverse proxy:
server {
listen 443 ssl;
server_name git.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/git.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Forgejo Actions CI/CD
Enable Actions in app.ini:
[actions]
ENABLED = true
Install and register a runner:
# Download forgejo-runner
wget https://code.forgejo.org/forgejo/runner/releases/download/v3.4.1/forgejo-runner-3.4.1-linux-amd64 \
-O /usr/local/bin/forgejo-runner
chmod +x /usr/local/bin/forgejo-runner
# Register (get token from Site Admin > Runners > Create Runner)
forgejo-runner register \
--instance https://git.yourdomain.com \
--token RUNNER_TOKEN \
--name production-runner \
--labels ubuntu-latest:docker://node:20-bullseye
# Start the runner
forgejo-runner daemon
Example Actions workflow:
# .forgejo/workflows/ci.yaml
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: make build
- name: Test
run: make test
Federation Configuration
Forgejo supports ActivityPub federation (experimental), allowing users to follow repositories and stars across instances:
# /etc/forgejo/app.ini
[federation]
ENABLED = true
sudo systemctl restart forgejo
Users on other Forgejo/Gitea instances can follow repositories using the format [email protected]/repo.
Migrating from Gitea
Forgejo is a drop-in replacement for Gitea. Migration is straightforward:
# 1. Stop Gitea
sudo systemctl stop gitea
# 2. Backup Gitea data
sudo -u gitea gitea admin dump --config /etc/gitea/app.ini \
--file /backup/gitea-backup.zip
# 3. Copy the data directory
sudo cp -r /var/lib/gitea/* /var/lib/forgejo/
# 4. Copy the configuration
sudo cp /etc/gitea/app.ini /etc/forgejo/app.ini
# 5. Run Forgejo migration
sudo -u forgejo forgejo migrate --config /etc/forgejo/app.ini
# 6. Start Forgejo
sudo systemctl start forgejo
All repositories, users, issues, and settings are preserved. Verify by browsing the web UI.
Administration Tasks
# Create an admin user via CLI
forgejo admin user create \
--username admin \
--password securepassword \
--email [email protected] \
--admin \
--config /etc/forgejo/app.ini
# Reset a user's password
forgejo admin user change-password \
--username alice \
--password newpassword \
--config /etc/forgejo/app.ini
# Regenerate Git hooks
forgejo admin regenerate hooks --config /etc/forgejo/app.ini
# Clean up old sessions
forgejo admin auth delete-user --username staleuser --config /etc/forgejo/app.ini
Troubleshooting
Cannot push via SSH:
# Verify SSH port is open
ss -tlnp | grep 2222
# Test SSH connection
ssh -T -p 2222 [email protected]
# Check authorized_keys permissions
ls -la /var/lib/forgejo/.ssh/
Actions runner not showing as online:
# Check runner logs
journalctl -u forgejo-runner -f
# Verify the runner token hasn't expired
# Regenerate from Site Admin > Runners
Database connection errors:
# Test database connectivity
psql -h 127.0.0.1 -U forgejo -d forgejo -c '\l'
# Check app.ini database section
sudo -u forgejo forgejo doctor check --config /etc/forgejo/app.ini
Webhook deliveries failing:
Check Site Administration > System Status > Queues for stuck jobs, and review individual webhook delivery logs under the repository settings.
Conclusion
Forgejo provides a lightweight, community-governed Git hosting platform that works as a seamless Gitea replacement. Its built-in Actions runner, federation support, and active community development make it a strong choice for self-hosted Git infrastructure. Updates release regularly, so monitor the Codeberg releases page and update promptly.


