CI/CD Integration
Automate HostFn deployments in your CI/CD pipeline with GitHub Actions, environment variables, and non-interactive mode.
HostFn is designed to work seamlessly in CI/CD pipelines. The --ci flag enables non-interactive mode, and SSH authentication is handled through environment variables so no interactive prompts are required.
The --ci Flag
When running in a CI/CD environment, pass the --ci flag to disable interactive prompts:
hostfn deploy production --ciIn CI mode, HostFn:
- Skips all interactive prompts (no confirmation dialogs)
- Reads SSH credentials from environment variables instead of the local keychain
- Outputs clean, machine-readable log lines
Environment Variables
HostFn uses the following environment variables for CI/CD authentication:
| Variable | Required | Description |
|---|---|---|
HOSTFN_HOST | No | Override the server from config (format: user@host) |
HOSTFN_SSH_KEY | Yes (if using key auth) | Base64-encoded SSH private key |
HOSTFN_SSH_PASSWORD | Yes (if using password auth) | SSH password |
HOSTFN_SSH_PASSPHRASE | No | Passphrase for the SSH key (if encrypted) |
SSH Key Setup
HostFn expects the SSH private key to be base64-encoded in the HOSTFN_SSH_KEY environment variable. This avoids issues with newlines and special characters in CI secret stores.
To encode your SSH key:
cat ~/.ssh/id_rsa | base64Copy the output and store it as a secret in your CI platform (e.g., GitHub Actions secret named SSH_PRIVATE_KEY).
Never commit SSH private keys to your repository. Always use your CI platform's secret management to store HOSTFN_SSH_KEY.
At runtime, HostFn decodes the key and uses it for both the SSH connection and rsync file transfers. A temporary key file is created with 0600 permissions during the rsync operation and deleted immediately afterward.
Password Authentication
If your server uses password-based SSH authentication instead of keys, set HOSTFN_SSH_PASSWORD:
export HOSTFN_SSH_PASSWORD="your-ssh-password"
hostfn deploy production --ciHost Override
Use HOSTFN_HOST to override the server address from your config. This is useful when your CI environment connects to servers via different hostnames or IP addresses than your local development machine:
export HOSTFN_HOST="deploy@10.0.0.50"
hostfn deploy production --ciGitHub Actions Workflow
Here is a complete GitHub Actions workflow that deploys on every push to the main branch:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Install HostFn
run: npm install -g hostfn
- name: Deploy to production
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ciRequired GitHub Secrets
Add the following secrets in your repository settings (Settings > Secrets and variables > Actions):
| Secret Name | Value |
|---|---|
SSH_PRIVATE_KEY | Base64-encoded SSH private key (cat ~/.ssh/id_rsa | base64) |
If your key has a passphrase, also add:
| Secret Name | Value |
|---|---|
SSH_PASSPHRASE | The passphrase for your SSH key |
And update your workflow to include it:
- name: Deploy to production
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
HOSTFN_SSH_PASSPHRASE: ${{ secrets.SSH_PASSPHRASE }}
run: hostfn deploy production --ciMonorepo CI Deployment
For monorepos, use the --service flag to deploy individual services. This lets you set up separate deployment jobs or deploy only the services that changed.
Deploy All Services
name: Deploy All Services
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy all services
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ciDeploy Specific Services
name: Deploy Services
on:
push:
branches: [main]
jobs:
deploy-account:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy account service
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ci --service account
deploy-auth:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy auth service
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ci --service authDeploy on Changed Paths
To deploy services only when their code changes, use path filters:
name: Deploy Changed Services
on:
push:
branches: [main]
jobs:
deploy-account:
runs-on: ubuntu-latest
if: contains(github.event.head_commit.modified, 'services/account/')
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy account service
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ci --service account
deploy-auth:
runs-on: ubuntu-latest
if: contains(github.event.head_commit.modified, 'services/auth/')
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy auth service
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ci --service authStaging and Production Pipeline
A common pattern is to deploy to staging first, then promote to production:
name: Staged Deployment
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy to staging
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy staging --ci
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm install -g hostfn
- name: Deploy to production
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ciThe needs: deploy-staging ensures production only deploys after staging succeeds. The environment: production setting enables GitHub's environment protection rules (manual approval, required reviewers, etc.).
Dry Run in CI
Use --dry-run in your CI pipeline to preview deployments without executing them. This is useful for pull request checks:
- name: Deployment dry run
env:
HOSTFN_SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
run: hostfn deploy production --ci --dry-runNext Steps
- Local Deployment Mode -- Deploy from self-hosted runners
- Dry Run -- Preview deployments without executing
- Deployment Overview -- Understand the full deployment lifecycle