Because of an excellent article over at zellwk.com, it didn’t take me nearly as long to figure out how to deploy a static-generated site (Astro) to my hosting provider.
Requirements:
- SSH access to your server
Below is the deploy.yml
file that I put in the .github/workflows
folder. Works like a charm!
0. Overview
We need to generate four secrets in our repository settings for the deploy script to work:
- The private SSH key
- The SSH host
- The SSH username
- The directory where to publish our files
More detailed instructions in Zell’s blog above, below an abbreviated summary.
1. Generate a SSH key on your server
- Leave the passphrase empty; we cannot put that in GitHub Actions
- Give your generated key a proper name, like
github-actions
instead of the defaultid_rsa
; much easier to identify later
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
2. Add the public key to authorized_keys
On your server, add the newly generated key to authorized_keys
:
cat github-actions.pub >> ~/.ssh/authorized_keys
3. Add the private key to your repository secrets
- Create a new “Repository secret” under Settings, name it
SSH_PRIVATE_KEY
4. Find the IP address of your server
- Find the IP address of your server
- Create another repository secret,
SSH_HOST
, and paste your IP address in the value field
5. Find the name of your SSH user account
- Create yet another repository secret,
SSH_USER
, and put your SSH username into the value field
6. Create a secret for your publish directory
Perhaps mostly to keep the deploy script clean and reusable…
- Create another repository secret
PUB_DIR
and paste the path to your publish directory, like:
/home/username/domain.com/public_html
7. Add the deploy script to your repository
- Create
.github/workflows/deploy.yml
and use the below script to automatically publish on push to branches main or master
This will grab the built dist
directory, and copy the contents to your specified folder.
If your publish folder is named something else than dist
, change the last line of the script where it says ./dist/
to whatever your publish directory is named.
name: deploy changes
on:
push:
branches:
- master
- main
schedule:
- cron: '0 0 * * *' # Everyday at 12am
jobs:
deploy:
runs-on: ubuntu-latest
permissions: write-all
strategy:
matrix:
node-version: [18]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use pnpm
uses: pnpm/action-setup@v2.2.4
with:
version: 7
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build project
run: pnpm run build
- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_PRIVATE_KEY }}
known_hosts: unnecessary
- name: Adding known_hosts
run: ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy with rsync
run: rsync -avz ./dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.PUB_DIR }}