How to deploy a 11ty static website with github action, ssh and scp
Last updated December 30, 2023 / 1623 words, 9 min read
SSH login without password
The aim to login from our host machine, to the virtual private server, uitilizing the public/private key pair and ssh
Adding your identity with ssh-add on the host machine
$ ssh-add ~/.ssh/id_rsa # add the identity
Enter passphrase for /Users/brthlmy/.ssh/id_rsa:
Identity added: /Users/brthlmy/.ssh/id_rsa (/Users/brthlmy/.ssh/id_rsa)
$ ssh-add -L # see identities
ssh-rsa cfOS7u8AnrlrTes9ybnX/-IT9GHlwPRwVEwjTVohX6... /Users/brthlmy/.ssh/id_rsa
Securely copy the public key to the virtual private server from the host machine
$ ssh-copy-id brthlmy@33.258.11.2
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
brthlmy@33.258.11.2's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'brthlmy@33.258.11.2'"
and check to make sure that only the key(s) you wanted were added.
Login into virtual private server, without entering the password
If everything went well, we can now login in by doing:
$ ssh brthlmy@33.258.11.2
brthlmy@33.258.11.2: cat ~/.ssh/authorized_keys
ssh-rsa cfOS7u8AnrlrTes9ybnX/-IT9GHlwPRwVEwjTVohX6... /Users/brthlmy/.ssh/id_rsa
In the ~/.ssh/authorized_keys
folder of the brthlmy
user on the virtual private server,
the public key is added, this is equalivent to the ssh-add -L
command that we used on the host machine,
when we added the identity to ssh.
Creating a deployment private/public keypair
Since we are going to add the private key to the github repository credentials,
we will create a private/public keypair for a deployment user and copy that key also into
the ~/.ssh/authorized_keys
on the virtual private server.
On the host computer create a deploy private/public keypair for the deployment
$ ssh-keygen -t ed25519 -C 'example+deploy@example.com'
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/brthlmy/.ssh/id_ed25519): /Users/brthlmy/.ssh/id_example-deploy
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_example-deploy
Your public key has been saved in id_example-deploy.pub
The key fingerprint is:
SHA256:CP08KO3WZfUk9SZtQ2dN+ExxhtUJS3aQJIaq8daZO/2mnaPh9Yy1 example+deploy@example.com
The key's randomart image is:
+--[ED25519 256]--+
| . |
| + . |
| . B . |
| o * + |
| X * S |
| + O o . . |
| . E . o |
| . . o |
| . . |
+----[SHA256]-----+
Adding the id_example-deploy to the identities on the host machine
$ ssh-add ~/.ssh/id_example-deploy
Enter passphrase for /Users/brthlmy/.ssh/id_example-deploy:
Identity added: /Users/brthlmy/.ssh/id_example-deploy (example+deploy@example.com)
Use ssh-copy-id to securely copy the public key to the virtual private server from the host machine
$ ssh-copy-id brthlmy@33.258.11.2
Great, the ~/.ssh/authorized_keys
now contains, two public keys on the virtual private server!
Setup and configure github action workflow to upload the private repository
https://github.com/appleboy/ssh-action
Create github workflow action in the private repository
In the private cmplxsmpl.com
repository we will create a github action workflow file.
$ mkdir -p .github/workflows/
$ vim .github/workflows/deploy.yml
Copy and paste the content in the .github/workflows/deploy.yml
name: Deploy
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@v0.1.4
with:
host: $
username: $
key: $
passphrase: $
port: $
script: |
ls
The above deploy.yml
will login into the virtual private server using the private key.
For this to work, we will need to define the following secrets in the private github repository.
# | Action Input variable | Github secret | Value |
---|---|---|---|
1 | host | HOST | virtual private server ip |
2 | username | USERNAME | the username, that has the public key in the ~/.ssh/authorized_keys |
3 | key | SSHKEY | the private key, eg. id_example-deploy |
4 | passphrase | KEYPASSPHRASE | the password for the private key, eg id_example-deploy that we have created |
5 | port | PORT | the port of the ssh agent running on the virtual private server |
Head over to your Secrets > Actions in the private github repository, eg. https://github.com/your-organization/your-repository/settings/secrets/actions
Click on New repository secret
and add the github secrets.
On the host machine, copy the private key from ~/.ssh/id_example-deploy
$ pbcopy < ~/.ssh/id_example-deploy
And add the remaining github secrets.
- Verify that the github action works
We update the .github/workflows/deploy.yml
and push the code to the master
branch. Under the Action
tab, you should
see the workflow excecuting with the output:
*Output*
======CMD======
ls -ahl
======END======
out: total 2K
out: drwxr-xr-x 6 ... ... 4.0K Aug 10 09:54 .
out: drwxr-xr-x 3 root root 4.0K Jul 4 20:11 ..
out: -rw------- 1 ... ... 3.8K Aug 10 13:31 .bash_history
out: -rw-r--r-- 1 ... ... 220 Jul 4 20:11 .bash_logout
==============================================
✅ Successfully executed commands to all host.
==============================================
Allrighty, we have a deploy.yml setup, that is able to excecute commands on the remote host.
Building a basic static site with 11ty
-
Create Simple minimal 11ty PR
-
Define the deployment steps
# | Description |
---|---|
1 | checkout repository current branch, eg. master |
2 | yarn install dependencies |
3 | yarn build creates the output in _site |
4 | scp to the remote server _site files, eg. /home/brthlmy/cmplxsmpl.com/_site |
5 | create symbolic link to /var/www/cmplxsmpl.com/_site/ |
- Update the deploy.yml workflow
Documentation:
- https://github.com/actions/setup-node
- https://github.com/actions/checkout
- https://classic.yarnpkg.com/en/docs/cli/install/#toc-yarn-install-pure-lockfile
- https://nehalist.io/building-and-deploying-gatsby-sites-with-github-actions/
name: Deploy
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set Node.js
uses: actions/setup-node@master
with:
node-version: 14
- name: Install dependencies
run: yarn install --pure-lockfile
- name: Build
run: yarn run build
- name: Copy folder content recursively to remote
uses: garygrossgarten/github-action-scp@release
with:
verbose: true
local: _site
remote: .
host: $
port: $
username: $
privateKey: $
passphrase: $