如何使用Ansible实现GitHub/Bitbucket至Ubuntu服务器的自动化部署?
嘿,刚好你已经有GitHub Webhook的基础,迁移到Ansible其实挺顺畅的!我来一步步帮你梳理怎么替代原来的Node.js方案完成自动化部署~
核心逻辑其实和你原来的Node.js方案差不多:GitHub触发Webhook → 服务器接收请求 → 执行部署操作。只不过把中间的Node.js脚本换成Ansible Playbook来完成拉代码、重启服务这些标准化步骤,同时还能利用Ansible的模块简化配置(包括可选的Webhook自动化管理)。
这是最关键的部分,先写一个Playbook来完成拉取Git代码、重启服务的核心操作。假设你的服务用systemd管理(比如myapp.service),示例如下:
# deploy_app.yml - name: 自动化部署Git仓库到Ubuntu服务器 hosts: your_server_hostname # 替换成你的服务器主机名,要在inventory文件里配置好 become: yes # 需要sudo权限操作服务 tasks: - name: 确保Git已安装在服务器上 apt: name: git state: present update_cache: yes - name: 拉取master分支最新代码到部署目录 git: repo: 'https://github.com/你的用户名/你的仓库名.git' # 替换成你的仓库地址 dest: /var/www/your-app # 替换成你的实际部署目录 version: master # 对应Webhook触发的分支 force: yes # 强制拉取,覆盖本地临时修改(如果不需要可以去掉) - name: 安装Node.js项目依赖(如果是Node项目的话) npm: path: /var/www/your-app state: present - name: 重启应用服务 systemd: name: myapp.service state: restarted enabled: yes daemon_reload: yes
然后准备一个inventory文件(比如hosts.ini)来定义你的服务器:
[servers] your_server_hostname ansible_host=你的服务器IP ansible_user=ubuntu ansible_ssh_private_key_file=/本地路径/到/你的SSH密钥.pem
先手动测试这个Playbook能不能正常运行:
ansible-playbook -i hosts.ini deploy_app.yml
确保代码能拉取、服务能重启,这步没问题再往下走。
GitHub的Webhook会给你的服务器发POST请求,所以需要一个轻量服务来接收这个请求,然后触发上面的Playbook。因为你熟悉Node.js,也可以用Express写,这里给个Python Flask的示例(更轻量):
- 先安装依赖:
sudo apt install python3-flask
- 写一个
webhook_handler.py:
from flask import Flask, request import subprocess import logging # 配置日志,方便排查问题 logging.basicConfig(filename='webhook.log', level=logging.INFO) app = Flask(__name__) @app.route('/webhook', methods=['POST']) def handle_webhook(): # 强烈建议加上GitHub Webhook签名验证,防止恶意请求 # 具体可以参考GitHub官方文档的签名验证逻辑,这里先简化演示 logging.info("收到Webhook请求,开始触发部署...") # 调用Ansible Playbook result = subprocess.run( ['ansible-playbook', '-i', '/你的路径/到/hosts.ini', '/你的路径/到/deploy_app.yml'], capture_output=True, text=True ) # 记录部署日志 logging.info(f"部署输出: {result.stdout}") if result.stderr: logging.error(f"部署错误: {result.stderr}") return '部署已触发', 200 if __name__ == '__main__': # 生产环境别用Flask自带服务器,换成Gunicorn或者uWSGI更稳定 app.run(host='0.0.0.0', port=8000)
- 用systemd把这个服务管理起来,创建
/etc/systemd/system/webhook-handler.service:
[Unit] Description=Webhook Handler for Ansible Deploy After=network.target [Service] User=ubuntu WorkingDirectory=/你的路径/到/handler文件目录 ExecStart=/usr/bin/python3 webhook_handler.py Restart=always [Install] WantedBy=multi-user.target
- 启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable webhook-handler.service sudo systemctl start webhook-handler.service
- 开放端口(用UFW的话):
sudo ufw allow 8000/tcp
如果想更规范,可以用Nginx反向代理到80/443端口,还能加HTTPS。
回到GitHub仓库的Webhook设置,把Payload URL改成http://你的服务器IP:8000/webhook,Content Type选application/json,然后点“Test”触发一下,看看服务器上的Playbook是否运行,应用是否正常重启。
如果你不想手动在GitHub页面配置Webhook,可以用Ansible的github_hooks模块来自动创建/更新,示例Playbook:
# setup_github_webhook.yml - name: 自动配置GitHub Webhook hosts: localhost tasks: - name: 创建仓库的Push事件Webhook github_hooks: repo: 你的用户名/你的仓库名 name: web events: - push config: url: http://你的服务器IP:8000/webhook content_type: json active: yes token: 你的GitHub个人访问令牌 # 需要有repo权限的PAT
运行这个Playbook就能自动配置好Webhook,不用手动操作GitHub页面了。
- 签名验证必加:一定要给Webhook加上GitHub的签名验证,避免被恶意请求触发部署,具体实现可以查GitHub官方文档。
- 敏感信息加密:用Ansible Vault加密GitHub PAT、SSH密钥这类敏感内容,不要明文写在配置里。
- 日志监控:把Webhook和Playbook的日志整合到监控工具里,方便快速排查部署问题。
- 进阶用AWX:如果以后部署场景变复杂(多服务器、审批流程),可以试试AWX(开源版Ansible Tower),它自带Webhook触发功能,不用自己写接收服务。
内容的提问来源于stack exchange,提问作者Евгений Новиков

