GitHub Actions: Deploy to Server

Create a GitHub Action Workflow to deploy and rsync PHP code to your server.

I had previously been using DeployHQ to deploy a couple of my website apps to my Linode server. This tool allowed my to run some Composer commands, then SSH into my server and sync changed files. I had always used the free version, and some time this year it started having GitHub sync issues so I all but stopped deploying updates to my apps.

The last couple of years I have been working with GitHub Actions as my CI/CD tooling for different projects (personal and business). So I thought it was time to create a deploy workflow.

File Structure

You need to follow the GitHub Action structure: .github/workflows/$name.yml. In my case I used deploy.yml.

Lets give it a name, and an “on” action.

name: "Deploy to Linode"

      - master

The above workflow will show up in your GitHub repo’s Action tab, under workflows on the left.

The “on” action syntax in this case uses two events: push & workflow_dispatch.

push: This event will run when a push to a branch is triggered. In this case, merging into or pushing to master.

workflow_dispatch: This event is meant to be triggered manually from the Run Workflow dropdown and couple allow custom input fields (omitted in this example).


The meat of this workflow is to trigger a job on select events. So we will create a single multi step job.

    name: Deploy
    runs-on: ubuntu-latest 
The tagged name of the Job will show up inside the workflow name.


Now that we have our named job, we have to create the steps. Each step has a purpose, and some steps are required to run after another in a select order.

The following steps will do a few select actions:

  1. Checkout the current repo code.
  2. Make sure PHP is setup with additional (optional tools) using shivammathur/setup-php
  3. Run Composer install
  4. Run Composer update to delete development dependencies (--no-dev) before pushing to PROD.
  5. SSH into my server using burnett01/rsync-deployments and rsync the current working directory code into the remote_path defined as a repository secret in GitHub.
    • There are some great instructions in that repo. I also found this article to be helpful in creating a one off SSH key for these actions.
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
          php-version: "8.2"
          coverage: none
          tools: composer:v2
          COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Run composer install
        run: |
          composer install --no-interaction --optimize-autoloader

      - name: Run composer update with --no-dev
        run: |
          composer update --no-dev --no-interaction --optimize-autoloader

      - name: rsync deployment
        uses: burnett01/[email protected]
          switches: -avz --exclude '.git' --exclude '.github' --exclude '.gitignore'
          remote_path: ${{ secrets.DEPLOY_PATH }}
          remote_host: ${{ secrets.DEPLOY_HOST }}
          remote_user: ${{ secrets.DEPLOY_USER }}
          remote_key: ${{ secrets.DEPLOY_KEY }}

Final thoughts

With this simple workflow, I can now auto-deploy my custom git tracked code to my personal, and business apps. See the full script on Gist.


πŸ’πŸ½β€β™‚οΈ Husband to Jeana.
⚾️ Dodgers & Brewers.
πŸ’» PHP Engineer.
πŸŒπŸΌβ€β™‚οΈGolfer; ~14 HDC.
🌱 Hydroponic Gardner.
🍿 Plex nerd.
πŸš™ '15 WRX, '22 Model 3 LR, & '66 Corvette C2.

Follow me on Twitter @TheFrosty & Instagram @TheFrosty.

Articles: 292