100% Free • CI/CD Ready

GitHub Actions Generator
Automate Your Workflow

Generate GitHub Actions workflows for continuous integration and deployment. Create workflows for Node.js, Python, Docker builds, and more.Automate testing, building, and deployment with every push.

Node.js/Python/Docker
Pre-built Templates
Common Actions
Best Practices

Quick Templates

Workflow Configuration

Common Actions

Checkout
actions/checkout@v4
Setup Node.js
actions/setup-node@v4
Setup Python
actions/setup-python@v5
Setup Go
actions/setup-go@v5
Cache dependencies
actions/cache@v4
Docker Build & Push
docker/build-push-action@v5

Best Practices

  • Use specific versions for actions (e.g., @v4 instead of @latest)
  • Store secrets in GitHub Secrets, never commit them
  • Use caching to speed up workflows
  • Set up branch protection rules
  • Use matrix builds to test multiple versions
  • Add status badges to your README
  • Use concurrency to cancel outdated workflow runs
  • Keep workflows in .github/workflows/ directory

Powerful Features

Everything you need for CI/CD automation

Multi-Language Support

Generate workflows for Node.js, Python, Go, Java, Docker, and more with proper setup and caching.

Quick Templates

Start with pre-built templates for testing, building, and deploying common application types.

Best Practices

Built-in security and performance best practices for GitHub Actions workflows.

What is GitHub Actions?

GitHub Actions is a powerful continuous integration and continuous deployment (CI/CD) platform built directly into GitHub. It allows developers to automate software workflows, from simple tasks like running tests on every push to complex deployment pipelines that span multiple environments and services. With GitHub Actions, you can build, test, and deploy your code right from your repository without relying on external CI/CD services.

At its core, GitHub Actions uses YAML-based workflow files stored in the .github/workflows directory of your repository. These workflows define automated processes that trigger on specific events such as pushes, pull requests, scheduled times, or manual dispatches. Each workflow consists of one or more jobs, and each job contains a series of steps that execute commands or use pre-built actions from the GitHub Marketplace.

One of the greatest strengths of GitHub Actions is its ecosystem. The GitHub Marketplace offers thousands of pre-built actions created by the community and verified publishers. These actions handle common tasks like setting up programming languages, caching dependencies, deploying to cloud providers, sending notifications, and much more. You can combine these actions with custom shell commands to create workflows tailored to your specific needs.

GitHub Actions runs on GitHub-hosted runners or self-hosted runners. GitHub-hosted runners provide pre-configured virtual machines with Ubuntu Linux, Windows, and macOS environments. For specialized requirements or to reduce costs, you can set up self-hosted runners on your own infrastructure, including your VPS or local servers. This flexibility makes GitHub Actions suitable for projects of any size, from personal side projects to enterprise-scale applications.

GitHub Actions for Deployment

Deploying applications with GitHub Actions transforms your deployment process from a manual, error-prone task into an automated, repeatable workflow. Whether you are deploying to a VPS, cloud platform, or container orchestration system, GitHub Actions provides the flexibility to handle virtually any deployment scenario. The key is understanding how to securely connect to your target environment and execute deployment commands.

For VPS deployments, SSH-based deployment is the most common approach. You store your SSH private key as a GitHub secret and use actions like appleboy/ssh-action to execute remote commands. This allows you to pull the latest code, install dependencies, build your application, and restart services all within your workflow. You can also use rsync to synchronize files between the GitHub runner and your server, which is efficient for deploying static files or application bundles.

Docker-based deployments add another layer of reliability and consistency. Your workflow can build Docker images, push them to a container registry like Docker Hub or GitHub Container Registry, and then SSH into your server to pull and run the new image. This approach ensures that your production environment exactly matches your development and testing environments. You can also use Docker Compose to manage multi-container applications, orchestrating databases, caches, and your application containers together.

Security is paramount when deploying through CI/CD pipelines. GitHub Actions provides encrypted secrets that are never exposed in logs and are only available to workflows running in your repository. You should use secrets for SSH keys, API tokens, database credentials, and any other sensitive information. Additionally, consider using environment protection rules to require manual approval for production deployments, ensuring that changes are reviewed before going live.

Advanced deployment strategies like blue-green deployments, canary releases, and rolling updates are all achievable with GitHub Actions. By combining conditional logic, matrix builds, and reusable workflows, you can create sophisticated deployment pipelines that minimize downtime and reduce the risk of failed deployments. Many teams also integrate health checks and automatic rollback mechanisms to ensure that deployments do not negatively impact users.

Workflow Examples

Ready-to-use GitHub Actions workflow examples for common deployment scenarios.

Deploy Node.js to VPS

This workflow builds a Node.js application, copies files to your VPS via SSH, installs dependencies, and restarts the application using PM2.

name: Deploy Node.js to VPS

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build application
        run: npm run build

      - name: Deploy to VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --production
            npm run build
            pm2 restart myapp

Deploy Docker to VPS

Build a Docker image, push it to Docker Hub, then deploy to your VPS by pulling and running the new container.

name: Deploy Docker to VPS

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: myuser/myapp:latest,myuser/myapp:${{ github.sha }}

      - name: Deploy to VPS
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            docker pull myuser/myapp:latest
            docker stop myapp || true
            docker rm myapp || true
            docker run -d --name myapp -p 3000:3000 myuser/myapp:latest

Deploy with SSH and Rsync

Use rsync over SSH to efficiently synchronize files to your server, only transferring changed files.

name: Deploy with SSH and Rsync

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install and build
        run: |
          npm ci
          npm run build

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts

      - name: Deploy with rsync
        run: |
          rsync -avz --delete ./dist/ ${{ secrets.VPS_USER }}@${{ secrets.VPS_HOST }}:/var/www/myapp/

      - name: Restart application
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            pm2 restart myapp

Build and Push to Registry

Multi-platform Docker build with caching, pushing to GitHub Container Registry with proper tagging.

name: Build and Push to Registry

on:
  push:
    branches: [main]
    tags: ['v*']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Common Mistakes to Avoid

1Hardcoding Secrets in Workflow Files

Never include passwords, API keys, or SSH keys directly in your workflow YAML files. These files are version controlled and visible to anyone with repository access. Always use GitHub Secrets accessed via ${{ secrets.SECRET_NAME }}. Even for public repositories, secrets remain encrypted and are never exposed in logs.

2Not Caching Dependencies

Downloading dependencies on every workflow run wastes time and resources. Use the built-in caching with actions/setup-node, actions/setup-python, or the generic actions/cache action. Proper caching can reduce workflow execution time by 50% or more, especially for projects with many dependencies.

3Using Outdated Action Versions

Pinning actions to old major versions or not specifying versions at all can lead to security vulnerabilities and unexpected behavior. Always use specific versions like actions/checkout@v4 rather than actions/checkout@master. Regularly update your action versions to benefit from security patches and new features.

4Running All Jobs Sequentially

If your workflow has independent tasks, running them sequentially wastes time. Jobs run in parallel by default unless you specify dependencies with needs:. Structure your workflows so independent jobs like linting, testing, and security scanning run concurrently, then deploy only after all checks pass.

5Not Setting Timeout Limits

Workflows without timeout limits can run indefinitely if something goes wrong, consuming your Actions minutes. Always set timeout-minutes at the job or step level. A typical build should complete in under 10 minutes; set a reasonable limit like 15-20 minutes to catch runaway processes while allowing for occasional slowdowns.

Frequently Asked Questions

Common questions about GitHub Actions workflows and deployments.

How do I store secrets in GitHub Actions?

Navigate to your repository Settings, then Security, then Secrets and variables, and select Actions. Click New repository secret to add secrets like SSH keys, API tokens, or passwords. Access them in workflows using ${{ secrets.YOUR_SECRET_NAME }}. Secrets are encrypted, never shown in logs, and only available to workflows in your repository. For organization-wide secrets, configure them at the organization level.

How do I deploy to my VPS with SSH?

First, generate an SSH key pair and add the public key to your server's ~/.ssh/authorized_keys. Store the private key as a GitHub secret named SSH_PRIVATE_KEY. Then use the appleboy/ssh-action to execute remote commands:

- uses: appleboy/[email protected]
  with:
    host: ${{ secrets.VPS_HOST }}
    username: ${{ secrets.VPS_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /var/www/app
      git pull && npm ci && pm2 restart app

What's the difference between jobs and steps?

A workflow contains one or more jobs. Each job runs on a separate virtual machine (runner) and can run in parallel with other jobs unless dependencies are specified. A step is a single task within a job, either running a shell command or using an action. Steps within a job run sequentially and share the same filesystem, so files created in one step are available in subsequent steps of the same job.

How do I trigger on push to a specific branch?

Use the on.push.branches filter to trigger workflows only when pushing to specific branches:

on:
  push:
    branches:
      - main
      - 'release/**'
  pull_request:
    branches:
      - main

You can also use branches-ignore to exclude branches, or combine with paths to only trigger when specific files change.

How do I cache dependencies?

Most setup actions include built-in caching. For Node.js, use the cache option:

- uses: actions/setup-node@v4
  with:
    node-version: '20'
    cache: 'npm'  # or 'yarn' or 'pnpm'

For custom caching, use actions/cache with a unique key based on your lock file hash. The cache persists across workflow runs, dramatically speeding up subsequent builds.

How do I run jobs conditionally?

Use the if conditional to control when jobs or steps run:

jobs:
  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        if: success()
        run: ./deploy.sh

Common conditions include github.event_name, success(), failure(), always(), and checking environment variables or outputs from previous steps.

Simplify Your Deployments

While GitHub Actions provides powerful CI/CD automation, managing deployments to your VPS still requires careful configuration of SSH keys, deployment scripts, and server maintenance.

Server Compass eliminates this complexity with built-in GitHub integration, automatic deployments on push, zero-downtime updates, and a visual interface for managing your applications. Deploy Node.js, Python, Go, or Docker containers with just a few clicks.

GitHub Integration
Auto Deploy on Push
Zero-Downtime Updates
Self-Hosted