Forgejo with Actions Runner
Forgejo Git forge with GitHub Actions compatible CI/CD runners.
Overview
Forgejo is a self-hosted Git forge that emerged as a community-driven fork of Gitea, focusing on federation capabilities and user freedom. It provides comprehensive Git repository hosting with built-in issue tracking, pull requests, wikis, and project management features. What sets Forgejo apart is its commitment to remaining fully community-owned and its development of ActivityPub federation for decentralized collaboration across instances. This stack combines Forgejo with its dedicated Actions Runner to create a complete GitHub-alternative CI/CD platform. The PostgreSQL database handles repository metadata, user accounts, and issue tracking, while Redis accelerates session management and caches frequently accessed data. The Docker-in-Docker (DinD) container provides isolated build environments for CI/CD pipelines, ensuring that Actions workflows run securely without affecting the host system. This configuration is ideal for organizations seeking GitHub functionality with complete control over their code and infrastructure. Teams migrating from GitHub will find familiar Actions syntax compatibility, while the federation features position this stack for future decentralized development workflows. The combination delivers enterprise-grade Git hosting with modern CI/CD capabilities, all under open-source licenses.
Key Features
- GitHub Actions compatible workflow syntax with .forgejo/workflows/ directory support
- ActivityPub federation protocol for cross-instance collaboration and decentralized development
- Docker-in-Docker isolation for secure CI/CD pipeline execution without host contamination
- PostgreSQL JSONB storage for efficient Git metadata and issue tracking with complex queries
- Redis-backed session clustering and cache acceleration for multi-user repository access
- Forgejo Runner daemon with automatic job polling and distributed build execution
- Built-in container registry for Docker image publishing from CI/CD pipelines
- Advanced Git LFS support with PostgreSQL metadata tracking and Redis caching
Common Use Cases
- 1Self-hosted GitHub alternative for teams requiring code sovereignty and data control
- 2CI/CD automation for Docker applications with integrated container registry publishing
- 3Private Git hosting for sensitive projects with Actions-based testing and deployment
- 4Educational institutions teaching DevOps with GitHub-compatible workflow syntax
- 5Open source projects seeking federated collaboration across multiple Forgejo instances
- 6Compliance-focused organizations needing auditable Git operations and build processes
- 7Development teams migrating from GitHub while maintaining existing Actions workflows
Prerequisites
- Minimum 2GB RAM for PostgreSQL database operations and Redis caching
- Docker host with privileged container support for Docker-in-Docker functionality
- Ports 3000 (web UI) and 222 (SSH Git access) available on the host system
- Basic understanding of Git forge administration and CI/CD workflow concepts
- SSL certificate setup knowledge for production HTTPS deployment
- Familiarity with GitHub Actions syntax for workflow creation and debugging
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 forgejo: 3 image: codeberg.org/forgejo/forgejo:74 container_name: forgejo5 environment: 6 - USER_UID=10007 - USER_GID=10008 - FORGEJO__database__DB_TYPE=postgres9 - FORGEJO__database__HOST=db:543210 - FORGEJO__database__NAME=forgejo11 - FORGEJO__database__USER=forgejo12 - FORGEJO__database__PASSWD=${DB_PASSWORD}13 - FORGEJO__cache__ADAPTER=redis14 - FORGEJO__cache__HOST=redis://redis:6379/015 - FORGEJO__session__PROVIDER=redis16 - FORGEJO__session__PROVIDER_CONFIG=redis://redis:6379/117 - FORGEJO__actions__ENABLED=true18 volumes: 19 - forgejo-data:/data20 - /etc/timezone:/etc/timezone:ro21 - /etc/localtime:/etc/localtime:ro22 ports: 23 - "3000:3000"24 - "222:22"25 depends_on: 26 - db27 - redis28 networks: 29 - forgejo-network30 restart: unless-stopped3132 runner: 33 image: code.forgejo.org/forgejo/runner:3.3.034 container_name: forgejo-runner35 environment: 36 - DOCKER_HOST=tcp://docker-in-docker:237637 - DOCKER_TLS_VERIFY=138 - DOCKER_CERT_PATH=/certs/client39 volumes: 40 - runner-data:/data41 - docker-certs:/certs/client:ro42 depends_on: 43 - forgejo44 - docker-in-docker45 networks: 46 - forgejo-network47 restart: unless-stopped48 command: >49 sh -c "50 while ! nc -z forgejo 3000; do sleep 1; done;51 forgejo-runner daemon52 "5354 docker-in-docker: 55 image: docker:dind56 container_name: forgejo-dind57 privileged: true58 environment: 59 - DOCKER_TLS_CERTDIR=/certs60 volumes: 61 - docker-certs:/certs62 - dind-data:/var/lib/docker63 networks: 64 - forgejo-network65 restart: unless-stopped6667 db: 68 image: postgres:15-alpine69 container_name: forgejo-db70 environment: 71 - POSTGRES_USER=forgejo72 - POSTGRES_PASSWORD=${DB_PASSWORD}73 - POSTGRES_DB=forgejo74 volumes: 75 - postgres-data:/var/lib/postgresql/data76 networks: 77 - forgejo-network78 restart: unless-stopped7980 redis: 81 image: redis:7-alpine82 container_name: forgejo-redis83 volumes: 84 - redis-data:/data85 networks: 86 - forgejo-network87 restart: unless-stopped8889volumes: 90 forgejo-data: 91 runner-data: 92 docker-certs: 93 dind-data: 94 postgres-data: 95 redis-data: 9697networks: 98 forgejo-network: 99 driver: bridge.env Template
.env
1# Forgejo with Actions2DB_PASSWORD=secure_forgejo_password34# Runner registration token (get from Forgejo admin)5RUNNER_TOKEN=your_runner_tokenUsage Notes
- 1Forgejo at http://localhost:3000
- 2Register runner in Forgejo admin settings
- 3GitHub Actions compatible workflows
- 4Uses Docker-in-Docker for isolation
- 5Support for .forgejo/workflows/
Individual Services(5 services)
Copy individual services to mix and match with your existing compose files.
forgejo
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=${DB_PASSWORD}
- FORGEJO__cache__ADAPTER=redis
- FORGEJO__cache__HOST=redis://redis:6379/0
- FORGEJO__session__PROVIDER=redis
- FORGEJO__session__PROVIDER_CONFIG=redis://redis:6379/1
- FORGEJO__actions__ENABLED=true
volumes:
- forgejo-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
depends_on:
- db
- redis
networks:
- forgejo-network
restart: unless-stopped
runner
runner:
image: code.forgejo.org/forgejo/runner:3.3.0
container_name: forgejo-runner
environment:
- DOCKER_HOST=tcp://docker-in-docker:2376
- DOCKER_TLS_VERIFY=1
- DOCKER_CERT_PATH=/certs/client
volumes:
- runner-data:/data
- docker-certs:/certs/client:ro
depends_on:
- forgejo
- docker-in-docker
networks:
- forgejo-network
restart: unless-stopped
command: |
sh -c "
while ! nc -z forgejo 3000; do sleep 1; done;
forgejo-runner daemon
"
docker-in-docker
docker-in-docker:
image: docker:dind
container_name: forgejo-dind
privileged: true
environment:
- DOCKER_TLS_CERTDIR=/certs
volumes:
- docker-certs:/certs
- dind-data:/var/lib/docker
networks:
- forgejo-network
restart: unless-stopped
db
db:
image: postgres:15-alpine
container_name: forgejo-db
environment:
- POSTGRES_USER=forgejo
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=forgejo
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- forgejo-network
restart: unless-stopped
redis
redis:
image: redis:7-alpine
container_name: forgejo-redis
volumes:
- redis-data:/data
networks:
- forgejo-network
restart: unless-stopped
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 forgejo:5 image: codeberg.org/forgejo/forgejo:76 container_name: forgejo7 environment:8 - USER_UID=10009 - USER_GID=100010 - FORGEJO__database__DB_TYPE=postgres11 - FORGEJO__database__HOST=db:543212 - FORGEJO__database__NAME=forgejo13 - FORGEJO__database__USER=forgejo14 - FORGEJO__database__PASSWD=${DB_PASSWORD}15 - FORGEJO__cache__ADAPTER=redis16 - FORGEJO__cache__HOST=redis://redis:6379/017 - FORGEJO__session__PROVIDER=redis18 - FORGEJO__session__PROVIDER_CONFIG=redis://redis:6379/119 - FORGEJO__actions__ENABLED=true20 volumes:21 - forgejo-data:/data22 - /etc/timezone:/etc/timezone:ro23 - /etc/localtime:/etc/localtime:ro24 ports:25 - "3000:3000"26 - "222:22"27 depends_on:28 - db29 - redis30 networks:31 - forgejo-network32 restart: unless-stopped3334 runner:35 image: code.forgejo.org/forgejo/runner:3.3.036 container_name: forgejo-runner37 environment:38 - DOCKER_HOST=tcp://docker-in-docker:237639 - DOCKER_TLS_VERIFY=140 - DOCKER_CERT_PATH=/certs/client41 volumes:42 - runner-data:/data43 - docker-certs:/certs/client:ro44 depends_on:45 - forgejo46 - docker-in-docker47 networks:48 - forgejo-network49 restart: unless-stopped50 command: >51 sh -c "52 while ! nc -z forgejo 3000; do sleep 1; done;53 forgejo-runner daemon54 "5556 docker-in-docker:57 image: docker:dind58 container_name: forgejo-dind59 privileged: true60 environment:61 - DOCKER_TLS_CERTDIR=/certs62 volumes:63 - docker-certs:/certs64 - dind-data:/var/lib/docker65 networks:66 - forgejo-network67 restart: unless-stopped6869 db:70 image: postgres:15-alpine71 container_name: forgejo-db72 environment:73 - POSTGRES_USER=forgejo74 - POSTGRES_PASSWORD=${DB_PASSWORD}75 - POSTGRES_DB=forgejo76 volumes:77 - postgres-data:/var/lib/postgresql/data78 networks:79 - forgejo-network80 restart: unless-stopped8182 redis:83 image: redis:7-alpine84 container_name: forgejo-redis85 volumes:86 - redis-data:/data87 networks:88 - forgejo-network89 restart: unless-stopped9091volumes:92 forgejo-data:93 runner-data:94 docker-certs:95 dind-data:96 postgres-data:97 redis-data:9899networks:100 forgejo-network:101 driver: bridge102EOF103104# 2. Create the .env file105cat > .env << 'EOF'106# Forgejo with Actions107DB_PASSWORD=secure_forgejo_password108109# Runner registration token (get from Forgejo admin)110RUNNER_TOKEN=your_runner_token111EOF112113# 3. Start the services114docker compose up -d115116# 4. View logs117docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/forgejo-actions/run | bashTroubleshooting
- Runner registration fails with 'connection refused': Ensure Forgejo is fully started before runner attempts registration, check network connectivity between containers
- Actions workflows fail with Docker permission errors: Verify docker-in-docker container is running with privileged mode and proper TLS certificate mounting
- PostgreSQL connection timeout during startup: Increase DB_PASSWORD complexity, check PostgreSQL container logs for authentication failures or resource constraints
- Redis session data not persisting: Confirm Redis volume mounting and check for Redis memory limits causing data eviction in high-traffic scenarios
- Forgejo web interface returns 500 errors: Check database migration status and ensure PostgreSQL has sufficient disk space for repository metadata
- Git clone operations timeout: Verify SSH port 222 accessibility and check Forgejo SSH key configuration for the git user
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
forgejoforgejo-runnerpostgresqlredis
Tags
#forgejo#git#ci-cd#actions#self-hosted
Category
DevOps & CI/CDAd Space
Shortcuts: C CopyF FavoriteD Download