I am trying to use the container option in a GitHub Actions workflow to run the entire job in a docker container. How do I specify the login credentials to retrieve this docker image from a private repository on docker hub?
jobs:
build:
runs-on: ubuntu-18.04
container: private_org/test-runner:1.0
I have successfully used the following docker-login "action" to authenticate with docker hub as a "step", but this does not get performed until after the job-level container gets initialized.
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: azure/docker-login#v1
with:
username: me
password: ${{ secrets.MY_DOCKERHUB_PASSWORD }}
- name: test docker creds
run: docker pull private_org/test-runner:1.0
This was implemented recently. Use the following workflow definition:
jobs:
build:
container:
image: private_org/test-runner:1.0
credentials:
username: me
password: ${{ secrets.MY_DOCKERHUB_PASSWORD }}
Source:
https://github.blog/changelog/2020-09-24-github-actions-private-registry-support-for-job-and-service-containers/
Related
I built an image docker and push it (manually) to my Github packages (private package) then I pull it and run it and it works fine, now I want to share this image with a friend who wants to run it on his PC, I gave him the pull command but he got the following error: docker pull "url" Error response from demon : Head unauthorized
I know it is an authentication issue but since im new to GitHub package I don't know what I have to do to share the image correctly.
any idea about this issue please?
name: Publish Docker image
on:
release:
types: [published]
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout#v3
- name: Log in to Docker Hub
uses: docker/login-action#f054a8b539a109f9f41c372932f1ae047eff08c9
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action#98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: my-docker-hub-namespace/my-docker-hub-repository
- 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 }
I want to automatically create an image using github actions and upload it after testing
However, when this build is executed inside the container, Unable to connect to newly launched container. (probably the execution was successful)
Of course it works when I try to do the same thing without using containers (on the machine).
Why the connection was failed when I tried in docker container?
jobs:
build_and_test:
runs-on: my-runner
container:
image: my-image:tag
credentials:
username: ${{ secrets.ID }}
password: ${{ secrets.PW }}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
options: --user root
steps:
- uses: actions/checkout#v2
- name: build_image
run: |
...
# build image
...
- name: bvt_test
run: |
container=$(docker run --rm -itd -p ${port}:1234 ${new_image})
...
# test, but the connection failed
Thanks.
I try to build and push the docker image to GHCR (GitHub Container Registry).
Unfortunately, during the login process with docker/login-action#v1 action which uses a GITHUB_TOKEN as a password, I received an error.
Error: Error response from daemon: Get "https://ghcr.io/v2/": denied: denied
The entire workflow yaml manifest.
name: Docker CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-push:
name: Buid and push Docker image to GitHub Container registry
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout the repository
uses: actions/checkout#v2
- name: Login to GitHub Container registry
env:
GITHUB_USER: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: docker/login-action#v1
with:
registry: ghcr.io
username: $GITHUB_USER
password: $GITHUB_TOKEN
- name: Build and Push Docker Image
env:
REGISTRY: ghcr.io
OWNER: my-organization-name
IMAGE_NAME: ${{ github.repository }}
uses: docker/build-push-action#v2
with:
context: .
file: ./docker/Dockerfile
target: final
push: true
tags: |
$REGISTRY/$OWNER/$IMAGE_NAME:$(date +%s)
build-args: |
ENVIRONMENT=production
The error screenshot.
UPDATES
Set up job stage.
Current runner version: '2.285.1'
Operating System
Ubuntu
20.04.3
LTS
Virtual Environment
Environment: ubuntu-20.04
Version: 20211219.1
Included Software: https://github.com/actions/virtual-environments/blob/ubuntu20/20211219.1/images/linux/Ubuntu2004-README.md
Image Release: https://github.com/actions/virtual-environments/releases/tag/ubuntu20%2F20211219.1
Virtual Environment Provisioner
1.0.0.0-main-20211214-1
GITHUB_TOKEN Permissions
Contents: read
Metadata: read
Packages: write
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
Download action repository 'actions/checkout#v2' (SHA:ec3a7ce113134d7a93b817d10a8272cb61118579)
Download action repository 'docker/login-action#v1' (SHA:42d299face0c5c43a0487c477f595ac9cf22f1a7)
Download action repository 'docker/build-push-action#v2' (SHA:a66e35b9cbcf4ad0ea91ffcaf7bbad63ad9e0229)
Login to GitHub Container registry stage.
Run docker/login-action#v1
with:
registry: ghcr.io
username: $GITHUB_USER
password: $GITHUB_TOKEN
ecr: auto
logout: true
env:
GITHUB_USER: my-github-username
GITHUB_TOKEN: ***
Logging into ghcr.io...
Error: Error response from daemon: Get "https://ghcr.io/v2/": denied: denied
NOTE
The repository I work with is private and belongs to the organization that I'm founding.
The GitHub documentation says that is recommended to use GITHUB_TOKEN instead of PAT. https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
To authenticate to the Container registry within a GitHub Actions
workflow, use the GITHUB_TOKEN for the best security and experience.
If your workflow is using a personal access token (PAT) to
authenticate to ghcr.io, then we highly recommend you update your
workflow to use the GITHUB_TOKEN.
The issue is trying to use a environment variable GITHUB_TOKEN as a password to which a secret ${{ secrets.GITHUB_TOKEN }} was assigned.
Since the secret ${{ secrets.GITHUB_TOKEN }} assigns directly to the password everything works fine.
name: Docker CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-push:
name: Buid and push Docker image to GitHub Container registry
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout the repository
uses: actions/checkout#v2
- name: Login to GitHub Container registry
uses: docker/login-action#v1
env:
GITHUB_USER: ${{ github.actor }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
registry: ghcr.io
username: $GITHUB_USER
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Docker Image
env:
REGISTRY: ghcr.io
OWNER: my-organization-name
IMAGE_NAME: ${{ github.repository }}
uses: docker/build-push-action#v2
with:
context: .
file: ./docker/Dockerfile
target: final
push: true
tags: |
$REGISTRY/$OWNER/$IMAGE_NAME:$(date +%s)
build-args: |
ENVIRONMENT=production
Using env is still possible but the syntax is different.
Instead of this assignment
password: $GITHUB_TOKEN
This one should be used
password: ${{ env.GITHUB_TOKEN }}
If I understand it correctly, the first syntax can be used inside a workflow runner. In other cases in a workflow file the env context should be used.
https://docs.github.com/en/actions/learn-github-actions/environment-variables
To use the value of an environment variable in a workflow file, you
should use the env context. If you want to use the value of an
environment variable inside a runner, you can use the runner operating
system's normal method for reading environment variables.
I am using GitHub Actions to trigger the building of my dockerfile, it is uploading the container to GitHub Container Registry. In the last step i am connecting via SSH to my remote DigitalOcean Droplet and executing a script to pull and install the new image from GHCR. This workflow was good for me as I was only building a single container in the project. Now I am using docker compose as I need NGINX besides by API. I would like to keep the containers on a single dropplet as the project is not demanding in ressources at the moment.
What is the right way to automate deployment with Github Actions and Docker Compose to DigitalOcean on a single VM?
My currently known options are:
Skip building containers on GHCR and fetch the repo via ssh to start building on remote from source by executing a production compose file
Building each container on GHCR, copy the production compose file on remote to pull & install from GHCR
If you know more options, that may be cleaner or more efficient please let me know!
Unfortunatly I have found a docker-compose with Github Actions for CI question for reference.
GitHub Action for single Container
name: Github Container Registry to DigitalOcean Droplet
on:
# Trigger the workflow via push on main branch
push:
branches:
- main
# use only trigger action if the backend folder changed
paths:
- "backend/**"
- ".github/workflows/**"
jobs:
# Builds a Docker Image and pushes it to Github Container Registry
push_to_github_container_registry:
name: Push to GHCR
runs-on: ubuntu-latest
# use the backend folder as the default working directory for the job
defaults:
run:
working-directory: ./backend
steps:
# Checkout the Repository
- name: Checking out the repository
uses: actions/checkout#v2
# Setting up Docker Builder
- name: Set up Docker Builder
uses: docker/setup-buildx-action#v1
# Set Github Access Token with "write:packages & read:packages" scope for Github Container Registry.
# Then go to repository setings and add the copied token as a secret called "CR_PAT"
# https://github.com/settings/tokens/new?scopes=repo,write:packages&description=Github+Container+Registry
# ! While GHCR is in Beta make sure to enable the feature
- name: Logging into GitHub Container Registry
uses: docker/login-action#v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
# Push to Github Container Registry
- name: Pushing Image to Github Container Registry
uses: docker/build-push-action#v2
with:
context: ./backend
version: latest
file: backend/dockerfile
push: true
tags: ghcr.io/${{ github.repository }}:latest
# Connect to existing Droplet via SSH and (re)installs add. runs the image
# ! Ensure you have installed the preconfigured Droplet with Docker
# ! Ensure you have added SSH Key to the Droplet
# ! - its easier to add the SSH Keys bevore createing the droplet
deploy_to_digital_ocean_dropplet:
name: Deploy to Digital Ocean Droplet
runs-on: ubuntu-latest
needs: push_to_github_container_registry
steps:
- name: Deploy to Digital Ocean droplet via SSH action
uses: appleboy/ssh-action#master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.PRIVATE_KEY }}
port: ${{ secrets.PORT }}
script: |
# Stop all running Docker Containers
docker kill $(docker ps -q)
# Free up space
docker system prune -a
# Login to Github Container Registry
docker login https://ghcr.io -u ${{ github.repository_owner }} -p ${{ secrets.CR_PAT }}
# Pull the Docker Image
docker pull ghcr.io/${{ github.repository }}:latest
# Run a new container from a new image
docker run -d -p 80:8080 -p 443:443 -t ghcr.io/${{ github.repository }}:latest
Current Docker-Compose
version: "3"
services:
api:
build:
context: ./backend/api
networks:
api-network:
aliases:
- api-net
nginx:
build:
context: ./backend/nginx
ports:
- "80:80"
- "443:443"
networks:
api-network:
aliases:
- nginx-net
depends_on:
- api
networks:
api-network:
Thought I'd post this as an answer instead of a comment since it was cleaner.
Here's a gist: https://gist.github.com/Aldo111/702f1146fb88f2c14f7b5955bec3d101
name: Server Build & Push
on:
push:
branches: [main]
paths:
- 'server/**'
- 'shared/**'
- docker-compose.prod.yml
- Dockerfile
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout#v2
- name: Create env file
run: |
touch .env
echo "${{ secrets.SERVER_ENV_PROD }}" > .env
cat .env
- name: Build image
run: docker compose -f docker-compose.prod.yml build
- name: Install doctl
uses: digitalocean/action-doctl#v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: Log in to DO Container Registry
run: doctl registry login --expiry-seconds 600
- name: Push image to DO Container Registry
run: docker compose -f docker-compose.prod.yml push
- name: Deploy Stack
uses: appleboy/ssh-action#master
with:
host: ${{ secrets.GL_SSH_HOST }}
username: ${{ secrets.GL_SSH_USERNAME }}
key: ${{ secrets.GL_SSH_SECRET }}
port: ${{ secrets.GL_SSH_PORT }}
script: |
cd /srv/www/game
./init.sh
In the final step, the directory in my case just contains a .env file and my prod compose file but these things could also be rsyncd/copied/automated as another step in this workflow before actually running things.
My init.sh simply contains:
docker stack deploy -c <(docker-compose -f docker-compose.yml config) game --with-registry-auth
The with-registry-auth part is important since my docker-compose has image:....s that use containers in DigitalOcean's container registry. So on my server, I'd already logged in once when I first setup the directory.
With that, this docker command consumes my docker-compose.yml along with the environment vairables (i.e. docker-compose -f docker-compose.yml config will pre-process the compose file with the .env file in the same directory, since stack deploy doesn't use .env) and registry already authenticated, pulls the relevant images, and restarts things as needed!
This can definitely be cleaned up and made a lot simpler but it's been working pretty well for me in my use case.
I'm new to Docker and trying to perform CI using GitHub Actions.
Here's my .yml file on GitHub.
name: CI to Docker Hub
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check Out Repo
uses: actions/checkout#v2
- name: Login to Docker Hub
uses: docker/login-action#v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action#v1
- name: Build and push
id: docker_build
uses: docker/build-push-action#v2
with:
context: .
file: ./Dockerfile
push: true
tags: your-order-backend:latest
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}
I have added Secrets in my Github too of Docker Hub.
I'm not sure why, but it is failing at > exporting to image:
It is resloved!
In my case, there was no repo in the Docker Hub created whose tag I have passed here in the yml file.
I created the repo and it worked
for me I fixed it by changing "push: true" to "load: true"
In my case, Id needed to create the repo in dockerhub as in the response of Sagar, but the problem still were there. I'd recognized I was passing the tags incorrectly, fix it and the problem was gone. (You can See the official examples)
Before:
tags: ${{ github.sha }}, latest
After (correctly):
tags: |
henriqueholtz/fullcycle-gitops:${{ github.sha }}
henriqueholtz/fullcycle-gitops:latest