Drone CI
Container-native CI/CD platform with Gitea integration.
Overview
Drone is a container-native continuous integration and continuous deployment (CI/CD) platform that was created by Brad Rydzewski and open-sourced in 2014. Unlike traditional CI/CD systems that require complex server setups and agent management, Drone executes build pipelines inside ephemeral Docker containers, making it naturally scalable and consistent across different environments. Each pipeline step runs in isolation with exactly the resources and dependencies it needs, eliminating the 'works on my machine' problem that plagues many CI/CD implementations.
This stack combines Drone with Gitea to create a completely self-hosted development workflow that rivals GitHub Actions or GitLab CI. Gitea serves as the lightweight Git repository host, providing pull requests, issue tracking, and user management, while Drone handles the automated testing, building, and deployment pipelines. The integration works through OAuth2 authentication and webhooks, so when developers push code to Gitea repositories, Drone automatically triggers the appropriate build pipelines defined in .drone.yml files.
This combination is particularly valuable for teams that want complete control over their source code and CI/CD infrastructure without the complexity of GitLab or the cost of hosted solutions. Small to medium development teams, organizations with strict data sovereignty requirements, and companies building internal developer platforms will find this stack provides enterprise-grade CI/CD capabilities while running on minimal hardware resources.
Key Features
- Container-native pipeline execution with each step running in isolated Docker containers
- Native Gitea integration through OAuth2 with automatic webhook configuration for push and pull request triggers
- Declarative pipeline configuration using simple YAML syntax in .drone.yml files
- Docker-in-Docker build capabilities for building and pushing container images within pipelines
- Parallel step execution and matrix builds for testing across multiple environments simultaneously
- Built-in secret management with encrypted environment variables and external secret providers
- Conditional pipeline execution based on branch, tag, or file change patterns
- Plugin ecosystem with over 100 pre-built plugins for deployment, notifications, and integrations
Common Use Cases
- 1Small development teams needing self-hosted CI/CD without GitHub or GitLab dependencies
- 2Organizations with data sovereignty requirements that cannot use cloud-based CI/CD services
- 3Container-first development workflows where all applications are built and deployed as Docker images
- 4Internal developer platforms providing standardized CI/CD across multiple development teams
- 5Educational environments teaching DevOps practices with real CI/CD tooling
- 6Hybrid cloud deployments where code stays on-premises but deploys to multiple cloud providers
- 7Open source projects requiring free, unlimited private repository hosting with automated testing
Prerequisites
- Docker Engine 20.03+ with docker-compose or Docker Desktop with at least 2GB available RAM
- Minimum 4GB system RAM (Gitea requires 512MB, Drone server 1GB, runner containers variable)
- Available ports 3000 (Gitea web), 2222 (Gitea SSH), and 8080 (Drone web interface)
- Basic understanding of Git workflows, Docker containers, and YAML configuration syntax
- Access to Docker Hub or container registry for pulling pipeline images and pushing built artifacts
- SSL certificate and domain name for production deployments with webhook callbacks
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 gitea: 3 image: gitea/gitea:latest4 container_name: gitea5 environment: 6 USER_UID: 10007 USER_GID: 10008 volumes: 9 - gitea_data:/data10 ports: 11 - "3000:3000"12 - "2222:22"13 networks: 14 - drone1516 drone: 17 image: drone/drone:218 container_name: drone19 environment: 20 DRONE_GITEA_SERVER: http://gitea:300021 DRONE_GITEA_CLIENT_ID: ${DRONE_GITEA_CLIENT_ID}22 DRONE_GITEA_CLIENT_SECRET: ${DRONE_GITEA_CLIENT_SECRET}23 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}24 DRONE_SERVER_HOST: localhost:808025 DRONE_SERVER_PROTO: http26 volumes: 27 - drone_data:/data28 ports: 29 - "8080:80"30 depends_on: 31 - gitea32 networks: 33 - drone3435 drone-runner: 36 image: drone/drone-runner-docker:137 container_name: drone-runner38 environment: 39 DRONE_RPC_PROTO: http40 DRONE_RPC_HOST: drone41 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}42 volumes: 43 - /var/run/docker.sock:/var/run/docker.sock44 depends_on: 45 - drone46 networks: 47 - drone4849volumes: 50 gitea_data: 51 drone_data: 5253networks: 54 drone: 55 driver: bridge.env Template
.env
1DRONE_GITEA_CLIENT_ID=your-client-id2DRONE_GITEA_CLIENT_SECRET=your-client-secret3DRONE_RPC_SECRET=your-rpc-secretUsage Notes
- 1Docs: https://docs.drone.io/
- 2Setup Gitea first at http://localhost:3000
- 3Create OAuth2 app in Gitea: Settings > Applications
- 4Drone at http://localhost:8080
- 5Generate RPC secret: openssl rand -hex 16
- 6Pipeline config in .drone.yml in repository root
Individual Services(3 services)
Copy individual services to mix and match with your existing compose files.
gitea
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
USER_UID: 1000
USER_GID: 1000
volumes:
- gitea_data:/data
ports:
- "3000:3000"
- "2222:22"
networks:
- drone
drone
drone:
image: drone/drone:2
container_name: drone
environment:
DRONE_GITEA_SERVER: http://gitea:3000
DRONE_GITEA_CLIENT_ID: ${DRONE_GITEA_CLIENT_ID}
DRONE_GITEA_CLIENT_SECRET: ${DRONE_GITEA_CLIENT_SECRET}
DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
DRONE_SERVER_HOST: localhost:8080
DRONE_SERVER_PROTO: http
volumes:
- drone_data:/data
ports:
- "8080:80"
depends_on:
- gitea
networks:
- drone
drone-runner
drone-runner:
image: drone/drone-runner-docker:1
container_name: drone-runner
environment:
DRONE_RPC_PROTO: http
DRONE_RPC_HOST: drone
DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- drone
networks:
- drone
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 gitea:5 image: gitea/gitea:latest6 container_name: gitea7 environment:8 USER_UID: 10009 USER_GID: 100010 volumes:11 - gitea_data:/data12 ports:13 - "3000:3000"14 - "2222:22"15 networks:16 - drone1718 drone:19 image: drone/drone:220 container_name: drone21 environment:22 DRONE_GITEA_SERVER: http://gitea:300023 DRONE_GITEA_CLIENT_ID: ${DRONE_GITEA_CLIENT_ID}24 DRONE_GITEA_CLIENT_SECRET: ${DRONE_GITEA_CLIENT_SECRET}25 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}26 DRONE_SERVER_HOST: localhost:808027 DRONE_SERVER_PROTO: http28 volumes:29 - drone_data:/data30 ports:31 - "8080:80"32 depends_on:33 - gitea34 networks:35 - drone3637 drone-runner:38 image: drone/drone-runner-docker:139 container_name: drone-runner40 environment:41 DRONE_RPC_PROTO: http42 DRONE_RPC_HOST: drone43 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}44 volumes:45 - /var/run/docker.sock:/var/run/docker.sock46 depends_on:47 - drone48 networks:49 - drone5051volumes:52 gitea_data:53 drone_data:5455networks:56 drone:57 driver: bridge58EOF5960# 2. Create the .env file61cat > .env << 'EOF'62DRONE_GITEA_CLIENT_ID=your-client-id63DRONE_GITEA_CLIENT_SECRET=your-client-secret64DRONE_RPC_SECRET=your-rpc-secret65EOF6667# 3. Start the services68docker compose up -d6970# 4. View logs71docker 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/drone-ci/run | bashTroubleshooting
- Drone shows 'failed to find or parse .drone.yml': Ensure .drone.yml file exists in repository root with valid YAML syntax and proper indentation
- Build fails with 'Cannot connect to the Docker daemon': Verify /var/run/docker.sock is mounted in drone-runner and Docker daemon is accessible
- Gitea OAuth2 authentication fails: Check DRONE_GITEA_CLIENT_ID and CLIENT_SECRET match the OAuth2 application created in Gitea settings
- Pipeline builds never trigger: Confirm webhook delivery in Gitea repository settings and verify DRONE_SERVER_HOST matches accessible Drone URL
- Runner shows 'x509: certificate signed by unknown authority': Set DRONE_RPC_SKIP_VERIFY=true for self-signed certificates or add CA certificate to runner
- Builds timeout or hang indefinitely: Increase Docker daemon resources or add timeout limits to individual pipeline steps
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
Ad Space
Shortcuts: C CopyF FavoriteD Download