这篇文章和使用 GitHub Actions 不同的是:
- 代码托管在 GitHub 私有仓库
- CI/CD 在自己服务器执行
- 不想使用 GitHub Actions 分钟数
- 比 Jenkins / GitLab 更轻量
另一篇文章 : GitHub Actions + Hugo 构建 + rsync/SSH 部署到服务器
整体架构:
1
2
3
4
5
6
7
8
9
| GitHub Push
↓
GitHub Webhook
↓
Woodpecker CI
↓
Docker 中构建 Hugo
↓
rsync 部署到服务器
|
为什么选择 Woodpecker#
Woodpecker 是 Drone 的社区 Fork,特点:
- 轻量
- Docker-first
- YAML 简单
- 支持 GitHub / Gitea / Forgejo
- 非常适合 Hugo、静态博客、小型项目
资源占用通常只有几十 MB。
GitHub Actions → Woodpecker 的区别#
GitHub Actions:
Woodpecker:
Woodpecker 的每个步骤本质上是 Docker 容器。
Secret 注入方式#
GitHub Actions:
1
| ${{ secrets.SERVER_HOST }}
|
Woodpecker:
1
2
3
4
5
6
| environment:
SERVER_HOST:
from_secret: server_host
#读取 secret(server_host)
#注入环境变量 SERVER_HOST
|
安装 Docker#
服务器已经安装了则跳过
服务器:
1
2
| curl -fsSL https://get.docker.com | sh
sudo apt install docker-compose-plugin -y
|
验证:
创建 GitHub OAuth App#
创建路径:
1
2
3
4
5
6
| GitHub
→ 鼠标移动到头像
→ Settings
→ Developer settings
→ OAuth Apps
→ New OAuth App
|




Authorization callback URL 是 https://ci.example.com + /authorize

填写:
1
2
| Homepage URL -> Woodpecker首页
Callback URL -> Woodpecker首页
|
创建后保存:
1
2
| Client ID
Client Secret
|
ci.example.com 更改为自己服务器的地址
部署 Woodpecker#
创建目录:
1
2
| mkdir -p /opt/woodpecker
cd /opt/woodpecker
|
生成随机 secret,填写在 WOODPECKER_AGENT_SECRET 字段。
.env#
1
2
3
4
5
6
7
8
9
10
11
| WOODPECKER_HOST=https://ci.example.com
WOODPECKER_GITHUB=true
WOODPECKER_GITHUB_CLIENT=你的ClientID
WOODPECKER_GITHUB_SECRET=你的ClientSecret
WOODPECKER_AGENT_SECRET=随机字符串
WOODPECKER_OPEN=true
WOODPECKER_ADMIN=你的GitHub用户名
|
创建docker-compose.yml#
1
| nano docker-compose.yml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:v3
restart: always
ports:
- "8000:8000"
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=${WOODPECKER_OPEN}
- WOODPECKER_HOST=${WOODPECKER_HOST}
- WOODPECKER_GITHUB=${WOODPECKER_GITHUB}
- WOODPECKER_GITHUB_CLIENT=${WOODPECKER_GITHUB_CLIENT}
- WOODPECKER_GITHUB_SECRET=${WOODPECKER_GITHUB_SECRET}
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:v3
restart: always
command: agent
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
volumes:
woodpecker-server-data:
|
启动:
首次登录#
打开:
使用 GitHub 登录。
第一次登录后建议关闭开放注册:
然后重启容器:
1
2
3
4
5
| docker compose restart
# 如果重启没有效果,可以销毁容器再启动
docker compose down
docker compose up -d
|
激活仓库#
选择自己在GitHub上的私有hugo仓库,点击启用。
Woodpecker 会自动创建 GitHub Webhook。

Hugo 自动部署#
仓库根目录创建:
部署配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| when:
- branch:
- main
- master
event:
- push
clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
steps:
build:
image: hugomods/hugo:0.145.0-exts
commands:
- hugo --minify --cleanDestinationDir
deploy:
image: alpine:latest
environment:
SERVER_HOST:
from_secret: server_host
SERVER_USER:
from_secret: server_user
SERVER_PATH:
from_secret: server_path
SERVER_SSH_KEY:
from_secret: server_ssh_key
commands:
- apk add --no-cache openssh rsync
- mkdir -p ~/.ssh
- echo "$SERVER_SSH_KEY" > ~/.ssh/deploy_key
- chmod 600 ~/.ssh/deploy_key
- ssh-keyscan -T 10 -H "$SERVER_HOST" >> ~/.ssh/known_hosts
- |
rsync -rlvz --delete \
--exclude='.user.ini' \
-e "ssh -i ~/.ssh/deploy_key" \
public/ \
"$SERVER_USER@$SERVER_HOST:$SERVER_PATH/"
|
配置 Secret#



添加:
| Name | 内容 |
|---|
| server_host | 服务器 IP |
| server_user | SSH 用户 |
| server_path | 部署目录 |
| server_ssh_key | SSH 私钥 |
这些值怎么来的, 请查看这篇文章
工作流程#
以后只需要:
Woodpecker 会自动:
1
2
3
4
5
| GitHub Webhook
→ 拉代码
→ Hugo 构建
→ rsync 上传
→ 网站更新
|
