Automate Go Service Deployment with Systemd and GitHub Webhooks
16 views
To set up an automatic deployment pipeline for a Go service using systemctl and GitHub webhooks, you will follow these steps:
-
Prepare your Go service for deployment:
- Ensure your Go service is properly versioned and the code is hosted in a GitHub repository.
-
Set up a GitHub Webhook:
- Navigate to your GitHub repository's settings.
- Under "Webhooks," click "Add webhook."
- Enter the payload URL where GitHub will send HTTP POST requests when events are triggered; we'll set this up on your server.
- Select "application/json" as the content type.
- Choose the events that will trigger the webhook. For automatic deployments, you may want to choose "Push events."
- Save the webhook.
-
Set up your server to receive webhooks:
- You’ll need a service on your server that listens for these HTTP POST requests. This can be a simple HTTP server that receives the webhook and triggers the deployment script.
- Below is a simple Go application to listen for GitHub webhooks:
package main import ( "encoding/json" "fmt" "net/http" "os/exec" ) func handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed) return } var payload map[string]interface{} if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { http.Error(w, "Can't decode JSON body", http.StatusBadRequest) return } fmt.Println("Received webhook:", payload) go func() { cmd := exec.Command("/path/to/deploy-script.sh") err := cmd.Run() if err != nil { fmt.Println("Error during deployment:", err) } }() fmt.Fprintln(w, "Deployment triggered!") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }- Build and run this application on your server. Ensure port 8080 (or your chosen port) is accessible, and update the webhook URL accordingly.
-
Create a deployment script:
- Write a shell script (
deploy-script.sh) to pull the latest changes, compile the application, and restart thesystemdservice. - Example
deploy-script.sh:
#!/bin/bash echo "Pulling the latest code..." cd /path/to/your/app || exit git pull origin main echo "Building the Go service..." go build -o my-service echo "Restarting the systemd service..." sudo systemctl restart my-go-service echo "Deployment complete."- Make sure the script is executable:
chmod +x /path/to/deploy-script.sh
- Write a shell script (
-
Configure
systemdservice:- Create a
systemdservice file for your Go application, usually in/etc/systemd/system/my-go-service.service:
[Unit] Description=My Go Service After=network.target [Service] ExecStart=/path/to/your/app/my-service WorkingDirectory=/path/to/your/app Restart=always User=your-user Environment=GODEBUG=mdbtls=1 [Install] WantedBy=multi-user.target - Create a
-
Enable and start your service:
- Enable and start the service using
systemctl:sudo systemctl enable my-go-service sudo systemctl start my-go-service
- Enable and start the service using
-
Test the webhook setup:
- Push a change to your GitHub repository.
- Monitor the server logs and ensure that the Go service successfully rebuilds and restarts.
With this setup, every time you push changes to your GitHub repository, the webhook will notify your server, triggering the deploy-script.sh, which in turn pulls the changes, rebuilds your Go service, and restarts the systemd service. Make sure to secure your webhook listener by using a secret or validating payloads.