GitHub Actions CI/CD
Deploy automatically when you push to main.
Prerequisites
Section titled “Prerequisites”- slipp project deployed and working manually
- SSH key access configured
- GitHub repository
-
Generate deployment SSH key
Terminal window ssh-keygen -t ed25519 -C "github-actions-deploy" -f deploy_key -
Add public key to VPS
Terminal window # Copy public keycat deploy_key.pub# Add to VPS authorized_keysslipp exec "echo 'YOUR_PUBLIC_KEY' >> ~/.ssh/authorized_keys" -
Add secrets to GitHub
Go to Repository → Settings → Secrets and variables → Actions:
Secret Value SSH_PRIVATE_KEYContents of deploy_keySSH_HOSTYour VPS IP or hostname SSH_USERslippVAULT_PASSWORDYour Ansible vault password -
Create workflow file
Directory.github/
Directoryworkflows/
- deploy.yml
Workflow File
Section titled “Workflow File”name: Deploy
on: push: branches: [main] workflow_dispatch:
jobs: deploy: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Install slipp run: pip install slipp
- name: Create vault password file run: echo "${{ secrets.VAULT_PASSWORD }}" > .vault_pass
- name: Deploy env: ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass run: | slipp deploy
- name: Cleanup if: always() run: rm -f .vault_pass ~/.ssh/deploy_keyBuild and Deploy
Section titled “Build and Deploy”If you need to build first:
name: Build and Deploy
on: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup Node uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- name: Install and Build run: | npm ci npm run build
- name: Build Docker Image run: docker build -t myapp:${{ github.sha }} .
- name: Save Image run: docker save myapp:${{ github.sha }} > image.tar
- uses: actions/upload-artifact@v4 with: name: docker-image path: image.tar
deploy: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 with: name: docker-image
- name: Setup SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Transfer Image run: | cat image.tar | ssh -i ~/.ssh/deploy_key \ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} \ "docker load"
- name: Install slipp run: pip install slipp
- name: Create vault password file run: echo "${{ secrets.VAULT_PASSWORD }}" > .vault_pass
- name: Deploy env: ANSIBLE_VAULT_PASSWORD_FILE: .vault_pass SSH_KEY_FILE: ~/.ssh/deploy_key run: slipp deploy
- name: Cleanup if: always() run: rm -f .vault_pass image.tar ~/.ssh/deploy_keyEnvironment-Specific Deploys
Section titled “Environment-Specific Deploys”Deploy to different environments based on branch:
name: Deploy
on: push: branches: - main - staging
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Set environment run: | if [ "${{ github.ref }}" = "refs/heads/main" ]; then echo "DEPLOY_ENV=production" >> $GITHUB_ENV else echo "DEPLOY_ENV=staging" >> $GITHUB_ENV fi
- name: Deploy run: slipp deploy ${{ env.DEPLOY_ENV }}Notifications
Section titled “Notifications”Add Slack/Discord notifications:
- name: Notify Success if: success() run: | curl -X POST ${{ secrets.SLACK_WEBHOOK }} \ -H 'Content-type: application/json' \ -d '{"text":"Deployed ${{ github.repository }} to production"}'
- name: Notify Failure if: failure() run: | curl -X POST ${{ secrets.SLACK_WEBHOOK }} \ -H 'Content-type: application/json' \ -d '{"text":"Deploy failed for ${{ github.repository }}"}'