I created a github workflow (Build Image) that successfuly builds an image using a Dockerfile
and secrets.SSH_KEY
. But, my other workflow (Build and Upload Image) that should build and upload the image to github registry using same Dockerfile
secrets.SSH_KEY
fails with Load key "/root/.ssh/id_ed25519": invalid format
error (see below).
I tried passing SSH_PRIVATE_KEY="${{ secrets.SSH_KEY }}"
with and without quotes but I get same error. What can be the problem?
Build Image
name: Build Image
on:
release:
branches: [ "main" ]
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the Docker image
run: docker build . --build-arg SSH_PRIVATE_KEY="${{ secrets.SSH_KEY }}" --file Dockerfile --tag my_image
working-directory: ./docker
Build and Upload Image
name: Docker Image
on:
push:
release:
branches: [ "main" ]
types: [published]
env:
REGISTRY: ghcr.io
IMAGE_NAME: my_image
jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./docker
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
SSH_PRIVATE_KEY="${{ secrets.SSH_KEY }}"
Error
0.209 Cloning into 'my_repo'...
0.254 Warning: Permanently added the ECDSA host key for IP address '140.82.112.4' to the list of known hosts.
0.318 Load key "/root/.ssh/id_ed25519": invalid format
0.318 [email protected]: Permission denied (publickey).
0.320 fatal: Could not read from remote repository.
Dockerfile
FROM ubuntu:20.04
ARG SSH_PRIVATE_KEY
RUN mkdir /root/.ssh && chmod -R 700 /root/.ssh \
&& echo "${SSH_PRIVATE_KEY}" > /root/.ssh/id_ed25519 \
&& chmod 0400 /root/.ssh/id_ed25519 && echo "StrictHostKeyChecking no" > /root/.ssh/config \
&& ssh-keyscan github.com >> /root/.ssh/known_hosts
ARG WORKSPACE_DIR
RUN mkdir -p ${WORKSPACE_DIR}
WORKDIR ${WORKSPACE_DIR}
RUN git clone --depth 1 -b 0.1.0 [email protected]:private-repo/private-repo1.git \
&& git clone --depth 1 -b 0.1.0 [email protected]:private-repo/private-repo2.git \
&& git clone --depth 1 -b 0.21.0 https://github.com/public-repo/public-repo1.git
Had to dig fairly deep, but it seems the issue lies in a combination of how SSH keys should be formed and how GH actions / docker/build-push-actions is coded.
After having a look at https://serverfault.com/a/854212, you can see from the comments that even a missing newline can cause the error invalid format
. Since your build works just fine when building from command line, but not with the docker/build-push-action
. I initially thought the issue could be something small like this.
I was on the right track, but the issue was a bit bigger than just one newline missing. Inspecting the build log of the GH action gives a clue: it seems to expand the multiline variable too early:
--build-arg SSH_PRIVATE_KEY="*** --build-arg *** --build-arg *** --build-arg *** --build-arg *** --build-arg *** --build-arg *** --build-arg *** --build-arg ***"
This goes obviously wrong, and it seems to be the result how GH actions expands secrets / environment variables before they are inserted into the commands. This apparently parses all lines to a new build arg.
Surounding the whole build arg with quotations works:
build-args: |
"SSH_PRIVATE_KEY=${{secrets.SSH_KEY}}"
Result in the build log
/usr/bin/docker buildx build --build-arg SSH_PRIVATE_KEY=***
***
***
***
***
***
***
***
*** --iidfile /home/runner/work/_temp/docker-actions-toolkit-L9DUvR/iidfile --tag latest --metadata-file /home/runner/work/_temp/docker-actions-toolkit-L9DUvR/metadata-file --push .
I was able to pull the repository without an error with this format.