Use local Docker image in a GitHub action?
Asked Answered
P

2

24

I would like to setup a GitHub Action to build my project and run tests locally. As I use .devcontainer I have a Dockerfile in .devcontainer/Dockerfile that provide everything I need to build my project.

Now I would like to write a GitHub Action to build the project on every push. Locally I would have done this:

docker build -t local - < .devcontainer/Dockerfile
docker run -it -v $(pwd):/srv -w/srv local make test

GitHub actions looks cumbersome, but I eventually wrote this:

on: push
jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: check out repository
        uses: actions/checkout@v2
      - name: build project
        container:
          image: ".devcontainer/Dockerfile"
          volumes:
            - .:/srv
        run: make test

Unfortunately it does not like the container keyword.

Any clues?

Protasis answered 11/4, 2020 at 9:42 Comment(0)
M
26

The container key is designed for running publicly available dockerized actions, and is available under the job.<job_id> key, not the steps key. You do not need it to accomplish your task.

The GitHub runners have an extensive list of software installed already, including docker and docker compose.

You can easily run the same commands you run locally in your GitHub workflow.

steps:
- name: Check out code
  uses: actions/checkout@v3
- name: Build docker images
  run: docker build -t local < .devcontainer/Dockerfile
- name: Run tests
  run: docker run -it -v $PWD:/srv -w/srv local make test

I am running most of my workflows like this, only using docker-compose, so you end up with cleaner workflows:

steps:
- name: Check out code
  uses: actions/checkout@v3
- name: Build docker images
  run: docker compose build
- name: Setup database
  run: docker compose run setup
- name: Run tests
  run: docker compose run test
Megaspore answered 11/4, 2020 at 11:3 Comment(2)
what do your docker compose setup|test do? Also, how to you check in github that the tests inside of docker passed or failed? – Devito
@Devito setup and test are services defined in docker-compose.yml. docker-compose run test will relay the status code of your command, so if your test suite exits with status 1 (anything but 0 means error), that's the exit status that GitHub will see. This works πŸ‘Œ – Pestalozzi
P
2

The best solution is to build, publish and re-use a Docker image based on your Dockerfile.

I would advise to create a custom build-and-publish-docker.yml action following the Github documentation: Publishing Docker images.

Assuming your repository is public, you should be able to automatically upload your image to ghcr.io without any required configuration. As an alternative, it's also possible to publish the image to Docker Hub.

Once your image is built and published (based on the on event of the action previously created, which can be triggered manually also), you just need to update your tests.yml action so it uses the custom Docker image. Again, here is a pretty good documentation page about the container option: Running jobs in a container.

As an example, I'm sharing what I used in a personal repository:

  • Dockerfile: the Docker image to be built on CI
  • docker.yml: the action to build the Docker image
  • lint.yml: the action using the built Docker image
Pinniped answered 9/8, 2022 at 17:43 Comment(2)
In your lint.yml you are explicitly referencing the main tag (ghcr.io/delgan/qml-format:main) which is not set if the docker image is created in a feature branch/pull request. Do you know how to get the image corresponding to the current branch? – Simpatico
@Simpatico I didn't test it, but I suppose you can use GITHUB_REF_NAME environment variable in your Github actions. – Pinniped

© 2022 - 2024 β€” McMap. All rights reserved.