2

I'm using the below workflow code (found in the github documentation) to build and publish a docker image to the Github Container Registry.

name: Create and publish a Docker image

on:
  push:
    branches: ['release']
  pull_request: 
    branches: ['release'] 

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

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

  steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Log in to the Container registry
      uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    - name: Extract metadata (tags, labels) for Docker
      id: meta
      uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

    - name: Build and push Docker image
      uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}

This works and I now see a public docker image under "Packages" on the github repo. When I click on the image, I am directed to a github page with more information about the image (official docs here): "Install from the command line:" docker pull ghcr.io/OWNER/IMAGE_NAME:pr-75

And its Digest sha: sha256:04ea7757e34c4fae527bbe6fb56eb984f54543f2313775572f0817d696ecf48a

I want to add a new job to the same workflow, that pulls the image to a virtual machine using ssh.

deploy:
  - name: Deploy to Digital Ocean droplet via SSH action
    uses: appleboy/ssh-action@v0.1.4
    with:
      host: ${{ secrets.DO_HOST }}
      username: root
      key: ${{ secrets.DO_PRIVATE_SSHKEY }}
      port: 22
      script: |
        docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

This fails with: err: invalid reference format: repository name must be lowercase (lowercasing it is not enough, read on)

Of course I cannot hard-code docker pull ghcr.io/OWNER/IMAGE_NAME:pr-75 or the Digest sha, because each new branch will increment in its PR number, so the pr-75 tag will change.

How can I deploy the image that was just published? Seems I can either use the tag value or the sha and how can I retrieve those values in real time?

Oliver Angelil
  • 1,099
  • 15
  • 31
  • The error `err: invalid reference format: repository name must be lowercase` is often an indication that one of your variables isn't expanding the way you think it is. What is the output of `echo ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}` if you stick that in a `run` step before the deploy step? – larsks Jun 16 '22 at 11:37
  • I'm not familiar with the `appleboy/ssh-action` action, but if it shows you the output of the `script`, just add a `set -x` before the `docker pull` command to see exactly what command is being executed. – larsks Jun 16 '22 at 11:55
  • output of `echo ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}` is `ghcr.io/Ownername/RepoName`. If I lowercase, and then retrieve the tag, it should work. Do you know how the tag can be retrieved? Was just wondering what the recommended way to do this would be but have found nothing documented. – Oliver Angelil Jun 16 '22 at 12:04
  • 1
    It looks like [docker/metadata-action](https://github.com/docker/metadata-action) will include the current branch name as a tag. Since your workflow only runs on the `release` branch, you can just use `release` as the tag name. – larsks Jun 16 '22 at 12:09
  • Apologies the workflow also runs on any pull-request made to the release branch. I have edited the Q. Ok let me try that action to see if I can get the tag. – Oliver Angelil Jun 16 '22 at 12:13

1 Answers1

1

There are two jobs in the above workflow:

  1. "build-and-push-image"
  2. "deploy"

The first one uses the docker/metadata-action to retrieve the tag name ghcr.io/OWNER/IMAGE_NAME:pr-75 which is used in the next step to name the image when docker/build-push-action is used.

I have simply used the docker/metadata-action again in the second job:

deploy:
  needs: build-and-push-image
  runs-on: ubuntu-latest
  steps:
    - name: Extract metadata (tags, labels) for Docker
      id: meta
      uses: docker/metadata-action@69f6fc9d46f2f8bf0d5491e4aabe0bb8c6a4678a
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

    - name: Deploy to Digital Ocean droplet via SSH action
      uses: appleboy/ssh-action@v0.1.4
      with:
        host: ${{ secrets.DO_HOST }}
        username: root
        key: ${{ secrets.DO_PRIVATE_SSHKEY }}
        port: 22
        script: |
          docker pull ${{ steps.meta.outputs.tags }}
Oliver Angelil
  • 1,099
  • 15
  • 31