Introduction
This tutorial explains how to deploy a GitHub artifact to a server or Hetzner Storage Box via SSH. Whether you have a compiled application, a website, or any other file to host, this step-by-step guide will help you get it up and running in no time.
Automating artifact deployment from GitHub to your server or Storage Box enhances your development process, improves reliability, and ensures that your artifacts are readily available to your intended audience while maintaining security and cost-efficiency.
Advantages
Using GitHub Actions workflow to store artifacts built on GitHub onto your server or Storage Box offers several advantages:
-
Automation: Automating the process of building and deploying artifacts streamlines your development workflow. With GitHub Actions, you can trigger the deployment automatically whenever changes are pushed to your repository. This reduces manual intervention and potential human errors.
-
Consistency: Automated deployments ensure consistency in the artifacts you store on your server or Storage Box. Every time you push changes to your repository, GitHub Actions will build and deploy the latest version, eliminating the risk of deploying outdated or incorrect files.
-
Version Control: GitHub provides version control for your code and, by extension, your artifacts. Each deployment is associated with a specific commit or branch, making it easy to track changes and roll back to previous versions if necessary.
-
Security: By using GitHub Secrets to store sensitive information like SSH keys and server / Storage Box credentials, you can maintain a higher level of security. These secrets are encrypted and not exposed in your repository's history.
-
Scalability: GitHub Actions can handle a variety of deployment scenarios, from simple artifact uploads to complex deployment pipelines. As your project grows, you can expand and customize your workflow to accommodate evolving needs.
-
Flexibility: This approach gives you the flexibility to deploy various types of artifacts, including websites, applications, data files, and more. You can tailor the GitHub Actions workflow to meet your specific deployment requirements.
-
Collaboration: Multiple team members can collaborate on a project and use the same automated deployment process. This ensures that everyone is working with the latest version of the artifacts.
-
Monitoring and Logging: GitHub Actions provides monitoring and logging capabilities, allowing you to track the progress of deployments, identify any issues, and receive notifications in case of failures.
Advantages of Hetzner
-
Performance: Hetzner's infrastructure offers good performance, ensuring that your artifacts are served quickly to users, even if they are geographically distributed.
-
Cost-Efficiency: Hetzner Storage Box is a cost-effective solution for storing artifacts. You only pay for the storage you use, making it a budget-friendly choice, especially for long-term storage.
-
Accessibility: Hetzner Storage Box allows you to serve your artifacts over the web, making them easily accessible to your team or end-users. You can share direct download links or embed the artifacts in your applications.
-
High Availability: Hetzner Storage Box is designed to provide high availability and reliability. Your artifacts are stored on redundant storage systems, reducing the risk of data loss.
Prerequisites
Before we dive into the deployment process, make sure you have the following prerequisites in place:
-
GitHub Repository: You should have a GitHub repository containing the artifact you want to deploy.
-
Server or Hetzner Storage Box: If you're using a Storage Box, ensure the necessary SSH access credentials & external connectivity are enabled.
-
SSH Client: You need to have an SSH client installed on your local machine. If you're using Linux or macOS, you can use the built-in SSH client. On Windows, you can use PuTTY or another SSH client of your choice.
-
SSH key: You can create either an ED25519 key or an RSA key. On Linux, you can use the
ssh-keygen
comand (e.g.ssh-keygen -f <any-name> -t ed25519
). For more information, see Setting up an SSH key. On Windows, you can use PuTTYgen.
Example terminology
-
Remote server:
<203.0.113.1>
» Example user:holu
-
Hetzner Storage Box:
uXXXXX.your-storagebox.de
» Example user:xxxxx-sub2
-
SSH key pair
» Private key:<key-name>
» Public key:<key-name>.pub
Step 1 - Setting up the SSH key
GitHub needs an SSH key to access the server or Storage Box. This tutorial assumes that you created a new SSH key pair on your local machine. You have to save the private key on GitHub, and the public key on the server or Storage Box.
It is recommended to use a new SSH key pair that is only used for this deployment and for nothing else.
Step 1.1 - Saving the public key on the server or Storage Box
Server
On your local machine, run:
ssh-copy-id -i ~/.ssh/<key-name>.pub holu@<203.0.113.1>
You can also add the key manually. Copy the public key, connect to the server, and add the key in this file: ~/.ssh/authorized_keys
Storage Box
It is highly recommended to create a sub account restricted to a base folder within the Storage Box. When a sub account is created, a username & password are shared by Hetzner (in an ephemeral way). You can connect to the Storage Box base directory with those credentials and setup the public key.
Make sure the SSH support setting for your Storage Box is enabled.
-
Storage Box mounted on a server
If you have mounted the Storage Box on a server, you can switch to the base directory on that Storage Box & setup these credentials directly over there, no need of usingscp
orrsync
. -
Storage Box unmounted
If you are using Storage Box in an unmounted way, you can use the commands below.
On your local machine, run:
ssh -p 23 xxxxx-sub2@uXXXXX.your-storagebox.de mkdir .ssh
scp -p 23 -r ~/.ssh/<key-name>.pub xxxxx-sub2@xxxxx.your-storagebox.de:~/.ssh/authorized_keys
Note: Hetzner Storage Boxes only accept SSH connections on port 23. SSH defaults to port 22, so you have to specify port 23 while connecting.
Step 1.2 - Saving the private key on GitHub
To securely store the credentials and SSH key to your server or Hetzner Storage Box, you should use GitHub Repository Secrets.
- Navigate to your GitHub repository.
- Go to the "Settings" tab.
- In the left sidebar, click on "Secrets and variables" » "Actions"
- Click the "New repository secret" button.
Create three secrets:
Example name | Secret |
---|---|
ARTIFACT_SSH_KEY |
Add your SSH private key |
ARTIFACT_USERNAME |
Add your username on the server or Storage Box |
ARTIFACT_HOST |
Add the hostname of your server or Storage Box |
The name will be shown as plain text. The secret will be encrypted.
Step 2 - GitHub Actions
Now that the SSH key and credentials are set up, you can get started with the deployment.
In your repository, create the directory .github/workflows
. In this directory, add a new YAML file (e.g. deploy-artifact.yml
) with the content below.
Replace the following as needed:
Example name Secret ARTIFACT_SSH_KEY
ARTIFACT_HOST
ARTIFACT_USERNAME
If you used different names, replace the names of the secrets -p 22
The default SSH port is 22. If you have a Storage Box, replace "22" with port "23". ./your-artifact.ext
Make sure to use the actual name of your artifact and the correct path in your GitHub Repo ~/path/to/destination/your-artifact.ext
Change the path to a path that exists on your server or Storage Box In the example below, I'm using
scp
. You could also usersync
instead. Both binaries are available on ubuntu-latest image.
#Sample CD file
name: Deploy to server or Storage Box
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up SSH key
run: |
env
mkdir -p ~/.ssh
echo "${{ secrets.ARTIFACT_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -p 22 -t ed25519 ${{ secrets.ARTIFACT_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to server or Storage Box
run: |
rsync -azP -e "ssh -i $HOME/.ssh/id_ed25519 -p 22" ./your-artifact.ext ${{ secrets.ARTIFACT_USERNAME }}@${{ secrets.ARTIFACT_HOST }}:~/path/to/destination/your-artifact.ext
Step 3 - Trigger the Workflow
Push your changes to your GitHub repository. This will automatically trigger the GitHub Actions workflow. It will build and deploy your artifact to your server or Storage Box whenever there is a push.
At the moment, the workflow is triggered every single time you push changes to the repository. If you want to trigger the workflow exclusively when your-artifact.ext
is changed, you can replace on: push
in the YAML file above with:
on:
push:
paths:
- 'your-artifact.ext'
Conclusion
That's it! You've successfully set up GitHub Actions to build and deploy artifacts on your server or Hetzner Storage Box automatically. This workflow will make your deployment process more efficient and maintainable.