In today’s DevOps world, triggering automated actions such as code deployments or Docker builds through webhooks is a powerful and essential practice. Learn how to set up a simple and secure webhook listener on Ubuntu 24.04 using Python, Flask, and Nginx. Perfect for triggering CI/CD pipelines and automated deployments from GitHub, GitLab, or Bitbucket. This guide walks through every step from installation to production readiness, helping developers build lightweight DevOps workflows without complex tools.
Prerequisites
Before we begin, let’s ensure we have the following in place:
- A Ubuntu 24.04 dedicated server or KVM VPS.
- A basic programming knowledge.
- A domain name pointing to server IP.
Setup a Webhook Listener on Ubuntu with Nginx
Step 1: Update Ubuntu 24.04 Packages
Before we begin, ensure our system is up to date:
sudo apt update && sudo apt upgrade -y
Step 2: Install Required Packages
We’ll use Python for our webhook listener and Nginx as a reverse proxy.
sudo apt install python3 python3-pip python3.12-venv nginx -y
Create a Python3 virtual environment
python3 -m venv env
Activate it
source env/bin/activate
We also install gunicorn and flask to quickly create a Python-based webhook server:
pip3 install flask gunicorn
Step 3: Create the Webhook Listener Script
Let’s create a basic Flask app that will handle POST requests.
mkdir -p ~/webhook_listener
cd ~/webhook_listener
nano app.py
Paste the following code:
from flask import Flask, request
import subprocess
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
if request.method == 'POST':
# Run any script on trigger
subprocess.Popen(['/bin/bash', '/home/ubuntu/deploy.sh'])
return 'Webhook received and script triggered', 200
return 'Invalid method', 400
Make sure to replace /home/ubuntu/deploy.sh
with the path to our deployment script.
Step 4: Create the Deployment Script
Now, let’s write the script that gets triggered.
nano ~/deploy.sh
Example content:
#!/bin/bash
cd /home/ubuntu/our-project-directory
git pull origin main
./deploy.sh
Make it executable:
chmod +x ~/deploy.sh
Step 5: Run the Webhook Server with Gunicorn
We can now run the Flask app with gunicorn:
cd ~/webhook_listener
gunicorn -w 2 -b 127.0.0.1:5000 app:app
To keep it running persistently, we’ll set up a systemd service in the next step.
Step 6: Create a Systemd Service
sudo nano /etc/systemd/system/webhook.service
Paste the following content:
[Unit]
Description=Webhook Listener
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/webhook_listener
ExecStart=/usr/local/bin/gunicorn -w 2 -b 127.0.0.1:5000 app:app
Restart=always
[Install]
WantedBy=multi-user.target
Note: Repace /home/ubuntu/
with your directory path and User:ubuntu
with your user.
Enable and start the service:
sudo systemctl daemon-reexec
sudo systemctl enable webhook
sudo systemctl start webhook
Step 7: Configure Nginx as a Reverse Proxy
sudo nano /etc/nginx/sites-available/webhook
Add this configuration:
server {
listen 80;
server_name webhook.example.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Note: Repace webhook.example.com
with your domain name,
Enable the site and reload Nginx:
sudo ln -s /etc/nginx/sites-available/webhook /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Replace webhook.example.com
with our actual domain or server IP.
Step 8: Secure the Webhook URL (Recommended)
For security, we should:
- Use a secret token in the URL: /webhook?token=xyz123
- Restrict incoming IPs to GitHub, GitLab, etc. via firewall or Nginx
- Use HTTPS with Let's Encrypt:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d webhook.example.com
Step 9: Test the Webhook
We can test using curl:
curl -X POST http://webhook.example.com/webhook
Or by configuring our GitHub/GitLab repository webhook pointing to this URL. Once configured, a push event will trigger the script.
Conclusion
By following these steps, we’ve set up a fully working webhook listener on Ubuntu 24.04 using Python, Flask, Gunicorn, and Nginx. This system allows us to automate deployments, CI/CD triggers, and custom actions in a lightweight, secure, and extensible way.
This solution helps us simplify DevOps pipelines, especially in environments without full-scale automation tools like Jenkins or GitHub Actions. By securing it with a reverse proxy and SSL, we ensure it's production-safe.
Let’s build smarter workflows — one webhook at a time.