GitHub Actions
Automate your Viabl docs deployment with a GitHub Actions workflow.
GitHub Actions lets you automatically build and deploy your docs every time you push changes to your repository. No manual builds, no manual deploys.
How it works
git push → GitHub Actions triggers → viabl build → deploy to your server
The workflow installs the Viabl CLI, runs viabl build, then copies the .viabl/ folder to your server and restarts the running process.
Prerequisites
Your docs project is in a GitHub repository A server with Node.js 20+ and SSH accessSSH key pair — private key stored as a GitHub secret, public key on your server
viabl installed on the server or installed as part of the workflow
Setting up secrets
Go to your GitHub repository → Settings → Secrets and variables → Actions and add the following secrets:
SSH_HOSTsecretThe IP address or hostname of your server.
SSH_USERsecretThe SSH username to connect with. Example: ubuntu, root, deploy.
SSH_PRIVATE_KEYsecretThe private SSH key used to connect to your server. Paste the full contents of
your .pem or private key file.
SSH_PORTsecretThe SSH port on your server. Usually 22.
Basic workflow
Create .github/workflows/deploy.yml in your docs repository:
name: Deploy Docs
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Viabl CLI
run: npm install -g @viablkit/cli
- name: Build docs
run: viabl build
- name: Copy build to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
source: ".viabl/"
target: "/srv/my-docs"
rm: true
- name: Restart docs server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
cd /srv/my-docs
pm2 restart my-docs || pm2 start .viabl/start.js --name my-docsThis workflow uses appleboy/scp-action to copy files and
appleboy/ssh-action to run commands on your server. Both are well-maintained
open source GitHub Actions.
With Docker
If you are deploying with Docker, replace the copy and restart steps with a Docker build and run:
name: Deploy Docs
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Viabl CLI
run: npm install -g @viablkit/cli
- name: Build docs
run: viabl build
- name: Copy build to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
source: ".viabl/,Dockerfile"
target: "/srv/my-docs"
rm: true
- name: Build and restart Docker container
uses: appleboy/[email protected]
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
cd /srv/my-docs
docker build --no-cache -t my-docs.
docker rm -f my-docs|| true
docker run -d \
--name my-docs\
--restart unless-stopped \
-p 7777:7777 \
-e PORT=7777 \
viabl-docs
docker image prune -fWith Railway
If you are deploying to Railway, use the Railway CLI in your workflow instead:
- name: Install Railway CLI
run: npm install -g @railway/cli
- name: Deploy to Railway
run: railway up --service my-docs
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}Add RAILWAY_TOKEN as a GitHub secret — get it from your Railway account settings.
Caching the Viabl CLI
On every run the workflow installs the CLI from scratch. Speed this up by caching the global npm prefix:
- name: Cache Viabl CLI
uses: actions/cache@v4
with:
path: ~/.npm-global
key: viabl-cli-${{ runner.os }}
- name: Install Viabl CLI
run: |
npm config set prefix ~/.npm-global
npm install -g @viablkit/cli
echo "$HOME/.npm-global/bin" >> $GITHUB_PATHOnly deploy on changes to docs
If your docs repo also contains other code, trigger the workflow only when docs files change:
on:
push:
branches:
- main
paths:
- "**.mdx"
- "**.md"
- "docs.json"
- "public/**"
- "openapi.yaml"Full workflow with caching and path filtering
name: Deploy Docs
on:
push:
branches:
- main
paths:
- "**.mdx"
- "**.md"
- "docs.json"
- "public/**"
- "openapi.yaml"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Cache Viabl CLI
uses: actions/cache@v4
with:
path: ~/.npm-global
key: viabl-cli-${{ runner.os }}
- name: Install Viabl CLI
run: |
npm config set prefix ~/.npm-global
npm install -g @viablkit/cli
echo "$HOME/.npm-global/bin" >> $GITHUB_PATH
- name: Build docs
run: viabl build
- name: Copy build to server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
source: ".viabl/"
target: "/srv/my-docs"
rm: true
- name: Restart docs server
uses: appleboy/[email protected]
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
cd /srv/my-docs
pm2 restart my-docs || pm2 start .viabl/start.js --name my-docs