4 Deploying with GitHub Actions
This chapter introduces a practical path from manual deployments to automated, repeatable delivery using CI/CD pipelines. It frames automation as a way to achieve portability and scalability, moving beyond ad hoc scripts to predictable systems that can be recreated and scaled on demand. The focus is on GitHub Actions for building, testing, and deploying, alongside Ansible for declarative, document-based server configuration—together forming an end-to-end pipeline that centralizes secrets, reduces human error, and accelerates delivery.
First, the chapter establishes CI/CD concepts—continuous integration with automated tests, and continuous delivery/deployment—and then scaffolds a minimal GitHub Actions workflow defined in YAML under .github/workflows. It explains triggers (manual and on push), runners (Ubuntu), and steps (checkout and commands), and shows how to store and consume secrets safely for environment variables and credentials. The workflow evolves from a simple “Hello World” to executing remote commands over SSH using a purpose-built private key and a newly provisioned virtual machine, culminating in an automated installation of NGINX on the server through a secure, repeatable pipeline.
With the foundations in place, the chapter pivots to Ansible for desired-state configuration. A GitHub Actions workflow prepares the runner (Python, Ansible), sets inventory and config, verifies connectivity, and runs playbooks. Playbooks first install and ensure NGINX is running, then expand to full app deployments: for Python, creating a virtual environment, synchronizing source code, installing requirements, and configuring Supervisor and NGINX with handlers; for Node.js, adding the appropriate apt repository, installing Node, updating npm, syncing code, and applying the same Supervisor/NGINX pattern. By externalizing secrets, codifying infrastructure in Ansible, and orchestrating execution via GitHub Actions, the chapter delivers a reproducible, scalable deployment workflow applicable to one or many hosts.
GitHub Actions tab
GitHub Actions sidebar
GitHub Actions Run Workflow
GitHub Actions workflow run result
GitHub Actions secrets link
New GitHub Actions secret
Akamai Linode navigation bar: click SSH Keys.
Akamai Linode: paste new SSH key.
Akamai Linode: create VM GitHub Actions with SSH keys.
Akamai Linode: IP address assigned to GitHub Actions
GitHub Actions: add IP address secret.
GitHub Actions Ansible setup result
GitHub Actions Ansible install NGINX.
GitHub Actions Ansible deploy Python result
Summary
- Continuous integration is the process of constantly integrating code changes into a single source of truth, namely a Git repo.
- Continuous delivery is the process of constantly delivering code changes to a Git repo in preparation for deployment.
- Continuous deployment is the process of constantly deploying code changes to a production environment.
- Deploying consistent environments for your applications is essential to ensure your applications will work as intended.
- GitHub Actions workflows are designed to be easily understood and easy to use while still being incredibly flexible to the various tools we may need to use and automate.
- Ansible is a powerful tool that can be used to automate the installation and configuration of software on remote machines.
- NGINX is a powerful web server that sits in front of web applications to provide additional security and performance.
- Supervisor is a powerful process manager that can be used to ensure that our applications are always running.
- The YAML format is a staple of automation and deployment regardless of what programming language you write your applications in.
- Running applications on remote machines requires the systems to be continually updated and monitored to ensure the correct dependencies are installed and configured.
- Even with simple application design, the process to deploy applications can be complex and error prone.
- Node.js and Python runtimes can share a number of production dependencies, such as NGINX and Supervisor, but are different enough that they require specific configurations, causing more complexity and more potential for errors.
Road to Kubernetes ebook for free