docker.recipes

Drone CI

intermediate

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:latest
4 container_name: gitea
5 environment:
6 USER_UID: 1000
7 USER_GID: 1000
8 volumes:
9 - gitea_data:/data
10 ports:
11 - "3000:3000"
12 - "2222:22"
13 networks:
14 - drone
15
16 drone:
17 image: drone/drone:2
18 container_name: drone
19 environment:
20 DRONE_GITEA_SERVER: http://gitea:3000
21 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:8080
25 DRONE_SERVER_PROTO: http
26 volumes:
27 - drone_data:/data
28 ports:
29 - "8080:80"
30 depends_on:
31 - gitea
32 networks:
33 - drone
34
35 drone-runner:
36 image: drone/drone-runner-docker:1
37 container_name: drone-runner
38 environment:
39 DRONE_RPC_PROTO: http
40 DRONE_RPC_HOST: drone
41 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
42 volumes:
43 - /var/run/docker.sock:/var/run/docker.sock
44 depends_on:
45 - drone
46 networks:
47 - drone
48
49volumes:
50 gitea_data:
51 drone_data:
52
53networks:
54 drone:
55 driver: bridge

.env Template

.env
1DRONE_GITEA_CLIENT_ID=your-client-id
2DRONE_GITEA_CLIENT_SECRET=your-client-secret
3DRONE_RPC_SECRET=your-rpc-secret

Usage Notes

  1. 1Docs: https://docs.drone.io/
  2. 2Setup Gitea first at http://localhost:3000
  3. 3Create OAuth2 app in Gitea: Settings > Applications
  4. 4Drone at http://localhost:8080
  5. 5Generate RPC secret: openssl rand -hex 16
  6. 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 file
2cat > docker-compose.yml << 'EOF'
3services:
4 gitea:
5 image: gitea/gitea:latest
6 container_name: gitea
7 environment:
8 USER_UID: 1000
9 USER_GID: 1000
10 volumes:
11 - gitea_data:/data
12 ports:
13 - "3000:3000"
14 - "2222:22"
15 networks:
16 - drone
17
18 drone:
19 image: drone/drone:2
20 container_name: drone
21 environment:
22 DRONE_GITEA_SERVER: http://gitea:3000
23 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:8080
27 DRONE_SERVER_PROTO: http
28 volumes:
29 - drone_data:/data
30 ports:
31 - "8080:80"
32 depends_on:
33 - gitea
34 networks:
35 - drone
36
37 drone-runner:
38 image: drone/drone-runner-docker:1
39 container_name: drone-runner
40 environment:
41 DRONE_RPC_PROTO: http
42 DRONE_RPC_HOST: drone
43 DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
44 volumes:
45 - /var/run/docker.sock:/var/run/docker.sock
46 depends_on:
47 - drone
48 networks:
49 - drone
50
51volumes:
52 gitea_data:
53 drone_data:
54
55networks:
56 drone:
57 driver: bridge
58EOF
59
60# 2. Create the .env file
61cat > .env << 'EOF'
62DRONE_GITEA_CLIENT_ID=your-client-id
63DRONE_GITEA_CLIENT_SECRET=your-client-secret
64DRONE_RPC_SECRET=your-rpc-secret
65EOF
66
67# 3. Start the services
68docker compose up -d
69
70# 4. View logs
71docker compose logs -f

One-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 | bash

Troubleshooting

  • 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