Woodpecker CI 部署过程记录
本来说要写的,咕了一个月。
正好最近搞了台新的小鸡,准备把 CI 迁过去,顺便复习一下 Woodpecker CI 的搭建过程。
这里就直接绑定自建的 gitea 了,比较贴近实际使用场景。
环境
Debian 11
主要依赖: nginx
, docker
, docker-compose
使用 nginx 官方 mainline 源
sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| sudo tee /etc/apt/preferences.d/99nginx
sudo apt update
sudo apt install nginx
添加 docker 自有的镜像源
sudo apt-get update
# sudo apt-get install \
# ca-certificates \
# curl \
# gnupg \
# lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
在 Gitea 添加 OAuth2 Application
创建一个 OAuth2 应用,以便用户向其授权获取账户信息,并在 CI 运行时 clone 私有仓库。
登录 Gitea 实例。进入 Settings - Applications - Manage OAuth2 Applications (/user/settings/applications), 在 “Create a new OAuth2 Application” 中添加。
Application Name 随意,
Redirect URI 填写如 https://ci.example.com/authorize
, 将 ci.example.com/
换作自己的 URI 即可。
随后应该得到 Client ID 和 Client Secret, 其中的 ID 以 UUID 形式出现,而 Secret 需立即复制, 此后不会再显示。
启动容器
既然 官方也推荐用 docker 容器 ,那就用呗。
编写 docker-compose.yml
.
其中的环境变量需要自己填写。
WOODPECKER_OPEN=true
无需更改。WOODPECKER_ORGS
填写自己在 gitea 中的组织名称。WOODPECKER_ADMIN
填写自己在 gitea 中的 username.
WOODPECKER_HOST
填写 CI 将要用的 Hostname, 如 https://ci.example.com
. 能否在 path 下工作暂不清楚。WOODPECKER_AGENT_SECRET
有两处,需填写相同的值,不妨用 openssl rand -hex 32
生成。
WOODPECKER_GITEA=true
无需更改。WOODPECKER_GITEA_URL
填写 Gitea 的 URL, 例如 https://example.com/git
, https://git.example.com
.WOODPECKER_GITEA_CLIENT
填写刚才得到的 Client ID.WOODPECKER_GITEA_SECRET
填写刚才得到的 Client Secret.
WOODPECKER_SERVER_CERT
和 WOODPECKER_SERVER_KEY
直接留空,TLS 交给 nginx 处理,不会有影响。
# docker-compose.yml
version: '3'
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
restart: unless-stopped
ports:
- 127.0.0.1:8000:8000
volumes:
- ./server-data:/var/lib/woodpecker/
environment:
# - WOODPECKER_LOG_LEVEL=trace
- WOODPECKER_OPEN=true
- WOODPECKER_ORGS=<YOUR_ORG_NAME>
- WOODPECKER_ADMIN=<YOUR_ADMIN_NAME>
- WOODPECKER_HOST=<YOUR_CI_URL>
- WOODPECKER_AGENT_SECRET=<YOUR_AGENT_SECRET>
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=<YOUR_GITEA_URL>
- WOODPECKER_GITEA_CLIENT=<YOUR_GITEA_OAUTH2_APP_UUID>
- WOODPECKER_GITEA_SECRET=<YOUR_GITEA_OAUTH2_APP_SECRET>
- WOODPECKER_SERVER_CERT=
- WOODPECKER_SERVER_KEY=
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
command: agent
restart: unless-stopped
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=<YOUR_AGENT_SECRET>
配置反代
此处使用 nginx.
一定不要忘记申请证书!可以用 acme.sh 快速申请。我的踩坑经历
配置 HTTP Server.
# /etc/nginx/conf.d/ci.example.com.conf
server {
listen 127.0.0.1:8001 ssl http2;
server_name ci.example.com;
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|^$") {
return 404;
}
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
ssl_certificate /path/to/certificate;
ssl_certificate_key /path/to/certificate_key;
#keepalive_timeout 70;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.0.0.1;
ssl_protocols TLSv1.3;
# ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256;
ssl_prefer_server_ciphers on;
location / {
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;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://127.0.0.1:8000;
}
}
配置 stream 模块
# /etc/nginx/conf.d/stream.conf
stream {
map $ssl_preread_server_name $name {
ci.example.com ci;
}
upstream ci {
server 127.0.0.1:8001;
}
server {
listen *:443 reuseport;
include /etc/nginx/conf.d/whitelist.conf;
proxy_pass $name;
ssl_preread on;
}
}
然后把这两个配置 include 到对应的地方就行了。然后重启下 nginx.
systemctl reload nginx
安全性(可选)
把域名挂到 互联网皇帝 那里,各种防火墙拉满。
同时给 nginx 加个 IP 白名单。
验证
最后访问网址,应该可以看到啄木鸟和旁边的 login 按钮。
点击后,应自动跳转至预设的 Gitea 实例,获取 OAuth2 授权后即可登录。
随后就应该能进入界面,并添加项目了。