Vấn đề về các công cụ CI/CD cồng kềnh
Tôi đã từng thử chạy Jenkins trên một droplet DigitalOcean giá 5 USD/tháng để quản lý một dự án Python nhỏ. Đó là một thảm họa. Chỉ trong vài phút, trình diệt OOM (Out of Memory) của Linux đã chấm dứt tiến trình vì Jenkins tiêu tốn gần 1.5GB RAM ngay cả khi ở trạng thái chờ. Đối với các nhà phát triển độc lập hoặc nhóm nhỏ, các công cụ CI/CD truyền thống thường tạo cảm giác như “dùng dao mổ trâu để giết gà”.
Hầu hết các công cụ doanh nghiệp được thiết kế cho các cụm server khổng lồ, không phải cho môi trường VPS tinh gọn. Nếu bạn đang tự host một Git server như Gitea, bạn có lẽ muốn một pipeline có hiệu suất tương xứng. Bạn cần một hệ thống hoạt động âm thầm, tiêu thụ dưới 100MB RAM khi nhàn rỗi và chỉ thực sự sử dụng tài nguyên CPU khi thực hiện build code.
Đây là lúc Drone CI tỏa sáng. Nó được xây dựng hoàn toàn trên kiến trúc ưu tiên container (container-first). Mỗi bước trong pipeline của bạn chỉ đơn giản là một Docker container được khởi tạo, thực hiện nhiệm vụ và biến mất. Khi kết hợp với Gitea, bạn sẽ có trải nghiệm tương tự GitHub trên một máy chủ chỉ với 1GB RAM tổng cộng.
Tại sao nên chọn Drone CI và Gitea?
Gitea là một dịch vụ Git nhẹ được viết bằng Go. Nó đủ nhanh để chạy trên một chiếc Raspberry Pi trong khi vẫn cung cấp giao diện người dùng bóng bẩy. Drone CI cũng chia sẻ triết lý này. Thay vì một mạng lưới plugin phức tạp, Drone sử dụng một tệp .drone.yml tinh gọn nằm ngay trong repository của bạn.
Mô hình “Pipeline as Code” này đảm bảo logic build của bạn phát triển song hành cùng phần mềm. Vì Drone là container-native (thuần container), bạn không bao giờ phải cài đặt thủ công Node.js, Python hay Go trên máy chủ host. Nếu dự án cần Node 20, bạn chỉ cần kéo image node:20 cho bước cụ thể đó. Sự cô lập này giúp ngăn chặn hội chứng “chạy được trên máy tôi” và giữ cho hệ điều hành host luôn sạch sẽ.
Việc làm chủ bộ công cụ này mang lại lợi thế rất lớn. Bạn sẽ học được các nguyên tắc cốt lõi của điều phối container (container orchestration) và cô lập môi trường mà không gặp phải rào cản học thuật quá lớn như Kubernetes.
Thiết lập bộ công cụ tinh gọn của bạn
Chúng ta sẽ triển khai cả Gitea và Drone CI trên một máy chủ duy nhất bằng Docker Compose. Việc sử dụng mạng bridge dùng chung cho phép các container này giao tiếp an toàn mà không cần công khai mọi cổng ra internet.
Bước 1: Yêu cầu hệ thống
Một máy chủ Ubuntu 22.04 cơ bản với 1GB RAM và 1 CPU core là đủ cho thiết lập này. Đảm bảo bạn đã cài đặt Docker và plugin Compose. Bạn cũng sẽ cần một tên miền (ví dụ: ci.yourdomain.com) để xử lý các phản hồi OAuth một cách chính xác.
Bước 2: Cấu hình Docker Compose
Tạo một thư mục riêng và khởi tạo tệp cấu hình của bạn:
mkdir devops-stack && cd devops-stack
touch docker-compose.yml
Chèn cấu hình sau vào tệp. Thiết lập này định nghĩa dịch vụ Gitea, Drone Server (bộ não) và Drone Runner (cơ bắp).
version: '3.8'
services:
gitea:
image: gitea/gitea:1.21
container_name: gitea
restart: always
networks:
- ci-network
ports:
- "3000:3000"
- "222:22"
volumes:
- ./gitea:/data
drone-server:
image: drone/drone:2
container_name: drone-server
ports:
- "8080:80"
volumes:
- ./drone:/data
restart: always
networks:
- ci-network
environment:
- DRONE_GITEA_CLIENT_ID=${GITEA_CLIENT_ID}
- DRONE_GITEA_CLIENT_SECRET=${GITEA_CLIENT_SECRET}
- DRONE_GITEA_SERVER=http://gitea:3000
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_SERVER_HOST=ci.yourdomain.com
- DRONE_SERVER_PROTO=http
drone-runner:
image: drone/drone-runner-docker:1
container_name: drone-runner
restart: always
networks:
- ci-network
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_PROTO=http
- DRONE_RPC_HOST=drone-server
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_RUNNER_CAPACITY=2
- DRONE_RUNNER_NAME=main-runner
networks:
ci-network:
driver: bridge
Bước 3: Kết nối Gitea với Drone
Drone không có cơ sở dữ liệu người dùng riêng; nó dựa vào Gitea để xác thực. Đầu tiên, hãy khởi chạy Gitea:
docker-compose up -d gitea
- Truy cập vào
http://your-ip:3000và hoàn tất thiết lập ban đầu. - Đăng nhập và đi tới Settings -> Applications -> OAuth2 Applications.
- Tạo một ứng dụng mới tên là “Drone CI”.
- Đặt Redirect URI thành
http://ci.yourdomain.com/login. - Lưu lại Client ID và Client Secret ngay lập tức.
Bước 4: Bảo mật các Secret
Tạo một tệp .env. Việc này giúp giữ các thông tin nhạy cảm của bạn tách biệt khỏi tệp compose chính. Sử dụng một chuỗi ngẫu nhiên mạnh cho RPC secret để đảm bảo runner và server có thể giao tiếp an toàn.
GITEA_CLIENT_ID=id_cua_ban_tai_day
GITEA_CLIENT_SECRET=secret_cua_ban_tai_day
DRONE_RPC_SECRET=$(openssl rand -hex 16)
Bước 5: Triển khai
Khởi chạy toàn bộ hệ thống bằng một lệnh duy nhất:
docker-compose up -d
Truy cập http://ci.yourdomain.com. Drone sẽ chuyển hướng bạn đến Gitea để ủy quyền. Sau khi bạn nhấn “Authorize”, các repository trên Gitea của bạn sẽ xuất hiện trong bảng điều khiển Drone, sẵn sàng để được kích hoạt.
Bước 6: Tạo Pipeline đầu tiên của bạn
Để kiểm tra hệ thống, hãy thêm tệp .drone.yml vào thư mục gốc của bất kỳ repository nào. Đây là một ví dụ thực tế cho ứng dụng Node.js:
kind: pipeline
type: docker
# Tên của pipeline
name: test-and-deploy
steps:
- name: install-dependencies
image: node:20-slim
commands:
- npm install
- npm test
- name: notify-success
image: plugins/webhook
settings:
urls: https://discord.com/api/webhooks/your-id
content: "Build thành công!"
Ngay khi bạn push đoạn code này, Gitea sẽ gửi một webhook tới Drone. Drone sau đó sẽ kéo image node:20-slim, thực thi các bài test và tự dọn dẹp sau khi hoàn tất. Tổng tài nguyên sử dụng trong quá trình build này? Thường là dưới 200MB RAM.
Tổng kết
Tự host hệ thống CI/CD không nhất thiết phải tốn kém hay ngốn tài nguyên. Bằng cách kết hợp Docker, Drone và Gitea, bạn đã xây dựng được một pipeline chuyên nghiệp, riêng tư, nhanh chóng và cực kỳ hiệu quả. Bạn không còn bị ràng buộc bởi các gói tín dụng của nhà cung cấp đám mây hay các ứng dụng Java cồng kềnh.
Để tiến xa hơn, hãy cân nhắc thêm một reverse proxy như Caddy hoặc Nginx với Let’s Encrypt. Điều này sẽ cung cấp HTTPS và cho phép bạn chạy mọi thứ trên cổng 443 tiêu chuẩn. Khi đã thành thạo cú pháp YAML, bạn có thể khám phá các tính năng nâng cao như các bước build song song hoặc tự động upload Docker image lên một registry riêng.

