Beginner’s Guide: Build, Push, and Deploy Docker Image with GitHub Actions
Md. Abu Raihan Srabon
Posted on November 10, 2024
In this post, we’ll introduce GitHub Actions and explain how to use them for automating Docker image builds, pushing images to a self-hosted registry, and deploying them to a remote server. This guide is tailored for beginners who want to start simple and expand their knowledge over time.
- What’s GitHub Actions?
GitHub Actions is a powerful tool for automating software workflows directly within your GitHub repository. It allows you to build, test, and deploy your code directly from GitHub. You define your automation tasks as YAML files within your repository, and these tasks run on GitHub’s hosted servers (or self-hosted runners if you prefer).
Why use GitHub Actions?
- Seamless integration with GitHub repositories.
- Customization: Create workflows tailored to your project needs.
- Ease of use: Simple YAML configuration.
- What This Script Does
The given GitHub Actions script automates the CI/CD pipeline for building, tagging, and pushing a Docker image to a self-hosted registry, then deploying it to a remote server. Let’s dive into the main sections of the script and understand how each part works.
a. Checking Out the Code
- name: Checkout Code
uses: actions/checkout@v3
This step clones the repository into the GitHub Actions runner, enabling the workflow to access your project files.
b. Setting Up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
Docker Buildx allows the runner to build multi-platform images and use advanced build features.
c. Configuring and Logging into the Docker Registry
- name: Add Registry to /etc/hosts
run: |
echo "${{ secrets.HOSTS_ENTRY }}" | sudo tee -a /etc/hosts
- name: Configure Docker for Insecure Registry
run: |
sudo mkdir -p /etc/docker
echo '{ "insecure-registries": ["https://harbor.example.com"] }' | sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
- name: Log in to Docker Registry
uses: docker/login-action@v2
with:
registry: harbor.example.com
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
These steps set up Docker on the runner to connect to the self-hosted Harbor registry. It configures Docker to treat the registry as an insecure source (use this cautiously) and logs in using provided credentials.
d. Tagging with a Date-Time-Based Version
- name: Generate Date-Time-Based Tag
id: generate_tag
run: |
new_version=$(date -u +"v%Y.%m.%d.%H%M%S")
echo "Generated tag: $new_version"
echo "version=$new_version" >> $GITHUB_ENV
This step creates a version tag based on the current UTC date and time, ensuring unique version identifiers for each image build.
e. Building and Pushing the Docker Image
- name: Build Docker Image
run: |
PROJECT_NAME=$(echo "${GITHUB_REPOSITORY}" | cut -d'/' -f2)
docker build -f .docker/Dockerfile \
-t harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:${{ env.version }} -t harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:latest .
env:
GITHUB_REPOSITORY: ${{ github.repository }}
- name: Push Docker Image
run: |
PROJECT_NAME=$(echo "${GITHUB_REPOSITORY}" | cut -d'/' -f2)
docker push harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:${{ env.version }}
docker push harbor.example.com/${{ vars.PROJECT_NAME }}/$PROJECT_NAME:latest
env:
GITHUB_REPOSITORY: ${{ github.repository }}
This section builds the Docker image using the Dockerfile and tags it with both the generated version and latest. It then pushes the images to the Harbor registry.
f. Deploying to a Remote Server
- name: Deploy to Remote Server
if: success()
env:
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
DEPLOY_COMMANDS: ${{ secrets.DEPLOY_COMMANDS }}
run: |
echo "${SSH_PRIVATE_KEY}" > /tmp/private_key
chmod 600 /tmp/private_key
ssh -o StrictHostKeyChecking=no -i /tmp/private_key ${SSH_USERNAME}@${SSH_HOST} "${DEPLOY_COMMANDS}"
shell: bash
Finally, this step connects to a remote server via SSH and runs the deployment commands specified in the GitHub secret DEPLOY_COMMANDS
. This helps automate the release process.
Below is an image of the complete GitHub Actions script:
- What We Have Accomplished by Running This Script
By running this GitHub Actions workflow, we have:
- Automated the process of checking out code and setting up Docker on a GitHub-hosted runner.
- Built a Docker image from the code and tagged it with both a version and latest.
- Pushed the Docker image to a self-hosted Harbor registry.
- Deployed the image to a remote server using secure SSH commands.
This streamlines the CI/CD process, making development and deployment faster and more reliable.
- Link to GitHub Gist
For an easy reference and to adapt this workflow to your needs, you can find the complete script here on GitHub Gist.
Feel free to use this template as a starting point for automating your Docker workflows and deployment pipelines. With GitHub Actions, you can achieve seamless automation with just a few configuration steps!
Posted on November 10, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 10, 2024