yu.pitomets
yu.pitomets

Reputation: 1840

How to build, run and call docker container in Github Action

I need to build docker image form the source code of the current repository, run a container, then execute some API calls. How to do that with the github action?

name: Docs Generator
on:
  pull_request:
    types: [opened]

jobs:
  pr-labeler:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
          uses: actions/checkout@v2
          with:
            ref: ${{ github.event.pull_request.head.ref }}
            repository: ${{ github.event.pull_request.head.repo.full_name }}
          
      - name: Get the version
        id: vars
        run: echo ::set-output name=tag::$(echo ${GITHUB_REF:10})
        
      - name: Build the tagged Docker image
        run: docker build . --file Dockerfile --tag service:${{steps.vars.outputs.tag}}
        
      - name: Run docker image
        docker run -v ${{ inputs.path }}:/src service:${{steps.vars.outputs.tag}}

      - name: Call API
        run: |
          curl +x http://localhost:8080/test
       
       .....

Upvotes: 10

Views: 11266

Answers (2)

Sairam Krish
Sairam Krish

Reputation: 11731

We can achieve this with following approach.

Advantages :

  • No need to push the intermediate docker build
  • We can build docker in one step and use it in another step without pushing it to any registry
  • We need docker/build-push-action to build the docker and addnab/docker-run-action to run the docker.

The following example shows a unit testing flow. But the concept remains same with your flow.

...
jobs:
  unittest:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3    
      - uses: docker/setup-buildx-action@v2
      - uses: docker/build-push-action@v4
        with:
          context: .
          file: "Dockerfile.test"
          tags: localpytest:latest
          load: true
          cache-from: type=gha
          cache-to: type=gha,mode=max
          push: false
      - name: Run Pytest
        uses: addnab/docker-run-action@v3
        with:
          image: localpytest:latest
          run: pytest    

  • For addnab/docker-run-action, observe the load parameter. The default value for this is false. This has to be true to use an image from one step in another step.
  • For docker/build-push-action, observe the push parameter as false. So we are not pushing it to any docker registry.
  • Github also provides docker layer caching. This helps to improve speed in later builds.

Upvotes: 11

Igor Loskutov
Igor Loskutov

Reputation: 2344

For this purpose, you could use a combination of https://github.com/marketplace/actions/build-and-push-docker-images and https://github.com/addnab/docker-run-action

The first would build and publish a container, and the second would take this container and run your commands there.

The example is below. I don't use this setup myself but I have tested it. Replace username/container with your username and container.

name: Docker Image CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
    compile:
        name: Build and run the container
        runs-on: ubuntu-latest
        steps:
          - name: Set up QEMU
            uses: docker/setup-qemu-action@v1
          - name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v1
          - name: Login to DockerHub
            uses: docker/login-action@v1
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}
          - name: Build and push
            uses: docker/build-push-action@v2
            with:
              push: true
              tags: username/container
          - name: Check out the repo
            uses: actions/checkout@v2
          - name: Run the build process with Docker
            uses: addnab/docker-run-action@v3
            with:
                image: username/container:latest
                options: -v ${{ github.workspace }}:/data
                run: |
                    echo "Hello World"

Note that building a container is quite a long task and might deplete your Github Action limits quickly. You might consider building/publishing a container separately, or add better caching here (i.e. to rebuild it only on Dockerfile change)

Note that you need to set up DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets.

Instead of echo "Hello World", use the commands you want to run. The repo data will be in the /data directory, for this setup.

Upvotes: 4

Related Questions