So, you've made your website using Zola and want it to be automatically deployed to your server when you push to master on GitHub? It's actually rather easy to set up. I will be using Docker and Nginx to serve the website as well as Traefik as a reverse proxy in my examples as this is based on the setup providing automatic deployment for this very website but this should be easy to modify for your own setup.
Step 1: Create the service on the server
Create a folder at /srv/my-website.com
sudo mkdir /srv/my-website.com
Create a docker-compose.yml
file in the same folder:
version: "3.5"
services:
my-website-nginx:
image: Nginx:1.12-alpine
restart: always
networks:
- traefik-net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.my-website.rule=Host(`my-website.com`)'
- 'traefik.http.routers.my-website.entrypoints=websecure'
- 'traefik.http.routers.my-website.tls=true'
- 'traefik.http.routers.my-website.tls.certresolver=le'
volumes:
- ./Nginx:/etc/Nginx/conf.d/
- /srv/my-website.se/public/:/var/www
networks:
traefik-net:
external: true
Finally create a file at /srv/my-website.com/nginx/my-website.conf
server {
listen 80 default_server;
server_name my-website.com;
location / {
root /var/www/;
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
}
The docker-compose file when launched will run Nginx with the configuration file described above. It will simply serve everything placed in the /srv/my-website.com/public
folder statically.
The goal is to automatically build your Zola project and copy the resulting /public folder there.
Step 2: Create a user
For safety reasons we will now create a new user that only has permissions to modify /srv/my-website.com/
. This user will be used in the GitHub Action to copy the files over later.
Create a user:
sudo useradd github
Then give the user a password. This should only be used when testing the deployment process, any access via SSH should be trough keys only.
sudo passwd github
Then create a home folder for the new user, and give it ownership of /srv/my-website.com and it's home.
sudo mkdir /home/github
sudo chown -R github /srv/my-website.com
sudo chown -R github /home/github
Step 3: Set up GitHub secrets.
For the action and access to work we first need to generate a keypair using ssh-geygen
. Make sure to not enter a passphrase.
This will generate two keys: a public and a private key. Copy the public key to /home/github/.ssh/authorized_keys/
(the public key ends with .pub, the other is the private key).
Go to the GitHub project containing the Zola project, go to 'Settings', go to 'Actions' and then 'Secrets' and add the following:
- HOST: The URL to the server you will be deploying your website on.
- PORT: The port that accepts SSH on your server.
- USERNAME: The name of the user deploying to your server. If you followed my examples it would be
github
- KEY: The private key of the keypair you just generated.
After setting up the GitHub secrets you should delete the private key from where you used ssh-keygen
.
Finally repeat repeat this from part 2:
sudo chown -R github /home/github
This makes sure the github
user has access to the authorized public key.
Step 4: Set up a GitHub runner.
For the automatic deployment to work you need a GitHub runner. If you already have one skip this step but just make sure it has Zola installed or modify the action to install Zola.
First, create a GitHub Personal Access Token. On the GitHub website go to 'Settings', 'Developer settings' and then 'Personal access tokens'. Create a new one and give it access to repos and make sure to save it as it will only be displayed once.
Create a file Dockerfile
in srv/my-website.com
:
FROM myoung34/Github-runner
# Install build dependencies
RUN apt-get update && apt-get install -y cargo make libssl-dev g++
# Clone and build Zola
RUN git clone https://github.com/getzola/zola /zola
WORKDIR /zola
RUN cargo build --release --target x86_64-unknown-linux-gnu
RUN mv target/x86_64-unknown-linux-gnu/release/zola /usr/bin
# Go back to initial workdir to not break the base image
WORKDIR /
WORKDIR /actions-runner
This extends the myoung34/Github-runner
by installing the dependencies needed to build Zola and then builds Zola. This might take some time but is only necessary when rebuilding the image.
Then add the following lines to the previously defined docker-compose under services:
github-runner:
build: ./
environment:
REPO_URL: https://github.com/YourGithubUserName/YourZolaProjectRepo
RUNNER_NAME: my-website-runner
RUNNER_WORKDIR: /tmp/runner/work
ACCESS_TOKEN: $ACCESS_TOKEN
LABELS: linux,x64
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
- '/tmp/runner:/tmp/runner'
Replace $ACCESS_TOKEN
with your own Personal Access Token that you just generated.
Running docker-compose up
(add -d if you want it to run in the background) in /srv/my-website.com
should now start an Nginx server statically serving files in /public as well as a GitHub runner.
You can test that it works by putting anything into a index.html
file in /public
and visiting my-website.com/index.html
. To confirm that the GitHub runner is working visit your repo, go to to 'Settings', 'Actions' and then 'Runners' where it should now show up.
Step 5: Create the GitHub Action
In the repo containing your Zola project create the directories .github/workflows/
:
mkdir -p .github/workflows/
Then add a file called zola.yml
:
name: Zola
on:
push:
branches: [master]
jobs:
build:
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Zola Build
run: zola build
- name: Save Artifact
uses: actions/upload-artifact@v2
with:
name: public
path: public/
deploy:
needs: build
runs-on: self-hosted
steps:
- name: Downloads public Artifact
uses: actions/download-artifact@v2
with:
name: public
- name: Deploys to server
uses: burnett01/rsync-deployments@4.1
with:
switches: -ahvze --delete
path: public/
remote_path: /srv/my-website.se/public/
remote_host: ${{ secrets.HOST }}
remote_user: ${{ secrets.USERNAME }}
remote_key: ${{ secrets.KEY }}
remote_port: ${{ secrets.PORT }}
This described an GitHub Action with two jobs. The first job is called build
and first builds the project and then saves the resulting /public
folder as an artifact.
The second job called deploy
waits for build
to complete and then downloads the /public
folder artifact and uses rsync
to only copy the changes over to your server (including removing files).
If all the steps have been followed correctly you should now be able to push to the master branch of your repo and automatically have the website deployed!