Forgejo on a VPS: Community-Owned Git Forge as GitHub and GitLab Alternative
Forgejo is a community-owned fork of Gitea created when Gitea’s development became controlled by a single company. Forgejo maintains the same GitHub-like interface and API but with community governance, no corporate ownership, and stronger commitments to open-source principles. It supports federation (ActivityPub) allowing repositories to be discovered across Forgejo instances, and includes Forgejo Actions for CI/CD with GitHub Actions-compatible syntax.
Forgejo vs Gitea: Key Differences
- Governance: Forgejo is governed by a community organization (Codeberg e.V.); Gitea Inc. controls Gitea
- Federation: Forgejo is implementing ActivityPub federation — follow repos/users across instances
- License commitment: Forgejo has committed to remaining MIT licensed
- Compatibility: Fully API-compatible with Gitea — same clients, same Gitea Apps work
- Migration: Upgrade from Gitea to Forgejo is a drop-in (same database format)
Step 1: Docker Compose Setup
<code">mkdir -p /opt/forgejo && cd /opt/forgejo nano docker-compose.yml
<code">version: '3.8'
services:
forgejo:
image: codeberg.org/forgejo/forgejo:9
container_name: forgejo
restart: always
ports:
- "127.0.0.1:3000:3000"
- "0.0.0.0:2222:22" # SSH for git push
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__database__DB_TYPE=postgres
- FORGEJO__database__HOST=forgejo-db:5432
- FORGEJO__database__NAME=forgejo
- FORGEJO__database__USER=forgejo
- FORGEJO__database__PASSWD=${POSTGRES_PASSWORD}
- FORGEJO__server__DOMAIN=git.yourdomain.com
- FORGEJO__server__ROOT_URL=https://git.yourdomain.com/
- FORGEJO__server__SSH_DOMAIN=git.yourdomain.com
- FORGEJO__server__SSH_PORT=2222
- FORGEJO__actions__ENABLED=true
- FORGEJO__federation__ENABLED=true
volumes:
- forgejo_data:/data
forgejo-db:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_DB: forgejo
POSTGRES_USER: forgejo
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- forgejo_db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U forgejo"]
interval: 10s
timeout: 5s
retries: 5
volumes:
forgejo_data:
forgejo_db:
<code">echo "POSTGRES_PASSWORD=StrongForgejoDbPassword!" > .env chmod 600 .env docker compose up -d
Step 2: Nginx Reverse Proxy
<code">sudo nano /etc/nginx/sites-available/forgejo
<code">server {
listen 80;
server_name git.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
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;
client_max_body_size 200M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
}
}
<code">sudo certbot --nginx -d git.yourdomain.com sudo systemctl reload nginx
Step 3: Migrate from GitHub
<code"># Method A: Forgejo UI migration (recommended)
# + → Migrate Repository → GitHub
# Enter: repository URL, GitHub PAT
# Options: migrate issues, labels, milestones, releases, wiki
# Method B: Bulk migration via API
FORGEJO_TOKEN="your_admin_token"
GITHUB_TOKEN="your_github_token"
# List GitHub repos and migrate each:
for repo in $(curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user/repos | jq -r '.[].full_name'); do
curl -X POST https://git.yourdomain.com/api/v1/repos/migrate \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"clone_addr\": \"https://github.com/$repo\",
\"auth_token\": \"$GITHUB_TOKEN\",
\"uid\": 1,
\"repo_name\": \"$(basename $repo)\"
}"
done
Step 4: Forgejo Actions CI/CD
<code"># Install act runner for Forgejo Actions:
wget https://code.forgejo.org/forgejo/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 \
-O /usr/local/bin/act_runner
chmod +x /usr/local/bin/act_runner
# Register runner (get token from admin panel):
# Forgejo → Site Administration → Actions → Runners → Create Runner
act_runner register \
--instance https://git.yourdomain.com \
--token YOUR_RUNNER_TOKEN \
--name vps-runner \
--labels ubuntu-latest:docker://node:20
# Forgejo Actions workflow (GitHub Actions compatible):
# .forgejo/workflows/ci.yml (same syntax as .github/workflows/)
Step 5: Federation (Cross-Instance Following)
<code"># Forgejo federation allows users on different instances to interact # Enable federation in app.ini (done via env var above): # FORGEJO__federation__ENABLED=true # ActivityPub endpoint created automatically: # https://git.yourdomain.com/user/alice -> WebFinger discovery # https://git.yourdomain.com/@alice -> Actor profile # Star a repository from another Forgejo instance: # @[email protected] can star git.yourdomain.com/bob/myproject # Follow a user across instances via ActivityPub (future feature)
Step 6: Packages (Container Registry)
<code"># Forgejo includes a package registry (OCI container, npm, pip, etc.) # Enable: FORGEJO__packages__ENABLED=true (default: true) # Push Docker images: docker login git.yourdomain.com docker tag myapp:latest git.yourdomain.com/myorg/myapp:latest docker push git.yourdomain.com/myorg/myapp:latest # Pull: docker pull git.yourdomain.com/myorg/myapp:latest # npm packages: npm publish --registry https://git.yourdomain.com/api/packages/myorg/npm/
Getting Started
Forgejo with PostgreSQL uses 200–400 MB RAM. A 2 GB Ubuntu VPS at VPS.DO runs Forgejo comfortably for teams up to 50 developers. For organizations that previously self-hosted Gitea, migrating to Forgejo is a direct upgrade with the same database format — just change the Docker image. The community governance model ensures the project won’t be acquired, relicensed, or sunset.
Conclusion
Forgejo provides a complete, community-owned Git forge — code hosting, issue tracking, pull requests, Forgejo Actions CI/CD, container registry, and ActivityPub federation — under MIT license with community governance. For organizations self-hosting their code, Forgejo’s commitment to open-source governance and planned federation make it the most future-proof choice. The API is fully Gitea-compatible, so any tool or integration built for Gitea works identically with Forgejo.
Checkout bloodprills.com
October 20, 2026Great overview of hair and nail care.
Essential amino acids
October 20, 2026This is a valuable addition to the discussion.
Memory loss causes
October 20, 2026Very informative and relevant.
Ringing in ears causes
October 20, 2026This is a practical and readable resource.