1. I have the following servers: Ubuntu v22.04.1 (Linux) with LEMP (PHP v5.6 (I know it is old, but the legacy app requires it), MySQL v8.0.36, and Nginx).
  2. I also have a private GitHub repo with the app code I want to put on my Ubuntu server.
  3. I want to use Github Actions to connect to the Ubuntu server using SSH and to use SSH to connect to the private repo and pull the code every time the main branch acquires a push.

This is the code in my .yaml file that GitHub Actions uses to connect to the Ubuntu server and supposedly pull the GitHub repo code (this is the part I am struggling with).

# Workflow to deploy code to the Ubuntu LEMP server every time there's a push to the main branch.
name: Deploy to Ubuntu Server

# Control when the actions happen.
  # Triggers the workflow on push or pull request events but only for the main branch.
    branches: [ main ]
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab.

# A workflow run is made up of one or more jobs that can run sequentially or in parallel.
  # This workflow contains a single job called "deploy".
    name: Deploy
    # The type of runner that the job will run on.
    runs-on: ubuntu-latest
    # Steps represent a sequence of tasks that will be executed as part of the job.
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it.
      - name: Checkout code
        uses: actions/checkout@v4

      ## Deploy using SSH to server
      - name: Execute remote SSH commands and deploy
        uses: appleboy/ssh-action@master
          host: ${{ secrets.REMOTE_IP }}
          username: ${{ secrets.REMOTE_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            cd ${{ secrets.REMOTE_PATH }} &&
            git init &&
            git pull origin main [email protected]:<username>/<repo-name>.git &&
            git pull origin main &&
            php cli/migrate.php -v -d &&
            php cli/migrate.php -v &&
            rm -Rf shared/cache &&
            ln -nfs shared/cache files &&
            rm -Rf Capfile &&
            rm -Rf config/deploy* &&
            rm -Rf .gitignore &&
            rm -Rf .git &&
            rm -Rf README.md &&
            php cli/update_revision.php &&
            php cli/update_crontab.php &&
            mkdir -p shared/certs &&
            mkdir -p shared/files &&
            mkdir -p shared/cache &&
            touch shared/config.php &&
            if [ -d shared/pids ]; then rmdir shared/pids; fi &&
            if [ -d shared/system ]; then rmdir shared/system; fi &&
            if (crontab -l | grep -q LEAF_PRODUCTION=1); then echo /dev/null; else { crontab -l; echo "LEAF_PRODUCTION=1"; } | crontab -; fi &&
            if (grep -q LEAF_PRODUCTION=1 ~/.profile); then echo /dev/null; else echo "export LEAF_PRODUCTION=1" >> ~/.profile; fi

The issue is with this part of the code

git pull origin main [email protected]:<username>/<repo-name>.git &&

I need to use two sets of SHH keys.

  • One set to connect to the Ubuntu server (I have put the public key inside the server and the private key is stored as a GitHub Secret key) This part of the code works.
  • Another to connect to the private GitHub repo and clone the code there (basically the opposite, the private key is on the server, but the public key is stored as the private GitHub repo Deploy key).

Connecting to the Ubuntu server works, but I do not understand how I am supposed to provide the code with the second set of SHH keys to connect and clone the GitHub repo. The way the code is written now, it only uses the first set of SHH keys to connect to the Ubuntu server.

  • What is git pull origin main [email protected]:<username>/<repo-name>.git supposed to do? That doesn't fit any invocation of git pull I have seen before. And if you have put the key in the server, you shouldn't have to pass the key to the script.
    – muru
    Commented Apr 8 at 4:42
  • @muru The command does not have to be so long, but in short, it gets the code from the repository. I added the "origin main" to make sure that it only takes code from the main branch and no other. "<username>/<repo-name>" are placeholders. > And if you have put the key in the server, you shouldn't have to pass the key to the script. But how does the script know where and when to get the SHH key? I think the issue is that the SHH key on the server is just ignored.
    – ghost
    Commented Apr 8 at 4:49
  • Have you actually tested that command? That's not how git pull works.
    – muru
    Commented Apr 8 at 4:54
  • @muru I did, using GIT terminal, it worked.
    – ghost
    Commented Apr 8 at 7:33
  • Really? Can you post the output of it in that case?
    – muru
    Commented Apr 8 at 8:05

1 Answer 1


I tried a different method while waiting for comments and it worked.

  1. Instead of using SSH, I tried to create a Github Access Token, that provides access to that repo, but in a limited capacity. This can be done in your GitHub profile settings >> Developer Settings >> Personal Acces Tokens >> Fine-grained personal access tokens.
  2. I took the access token and added it to my Github Action secret.
  3. I used the secret to generate and pull the code from the following HTTPS URL: https://:<access_token>@github.com//<repo_name>.git

The issue with this method is that I had to abandon SSH for it to work. I believe there is a way to fix the SSH issues, but for now, my solution works.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .