From 91a1fadd1d69020c5ae80278f0b76b1f3aa88e0e Mon Sep 17 00:00:00 2001 From: tczekajlo Date: Wed, 24 Mar 2021 11:36:01 +0100 Subject: [PATCH] Use GitHub Actions for building Docker image --- .github/workflows/continous-integration.yml | 79 +++++++++++++++++++++ Dockerfile | 62 +++++++++++++--- docker-bake.hcl | 12 ++++ 3 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 docker-bake.hcl diff --git a/.github/workflows/continous-integration.yml b/.github/workflows/continous-integration.yml index 37afb5a30..2f0273c1e 100644 --- a/.github/workflows/continous-integration.yml +++ b/.github/workflows/continous-integration.yml @@ -126,6 +126,85 @@ jobs: COVERALLS_SERVICE_NAME: github run: poetry run coveralls + build_docker_image_set_env: + name: Prepare environment for Docker build + runs-on: ubuntu-latest + outputs: + # Tag name used for intermediate images created during Docker image builds, e.g. 3886 - a PR number + image_tag: ${{ steps.set_output.outputs.image_tag }} + steps: + # Set environment variables for a pull request + # + # In this scenario, we've created a PR #1234 + # + # Example output: + # IMAGE_TAG=1234 + - name: Set environment variables - pull_request + if: github.event_name == 'pull_request' && env.IS_TAG_BUILD == 'false' + run: | + echo "IMAGE_TAG=${{ github.event.number }}" >> $GITHUB_ENV + + # Set environment variables for a tag + # + # In this scenario, we've pushed the '2.4.1' tag + # + # Example output: + # IMAGE_TAG=2.4.1 + - name: Set environment variables - push - tag + if: github.event_name == 'push' && env.IS_TAG_BUILD == 'true' + run: | + TAG_NAME=${GITHUB_REF#refs/tags/} + echo "IMAGE_TAG=${TAG_NAME}" >> $GITHUB_ENV + + # Set environment variables for a branch + # + # In this scenario, we've pushed changes into the main branch + # + # Example output: + # IMAGE_TAG=main + - name: Set environment variables - push - branch + if: github.event_name == 'push' && env.IS_TAG_BUILD == 'false' + run: | + BRANCH_NAME=${GITHUB_REF#refs/heads/} + echo "IMAGE_TAG=${BRANCH_NAME}" >> $GITHUB_ENV + + - name: Set output + id: set_output + run: | + echo "::set-output name=image_tag::${{ env.IMAGE_TAG }}" + + build_docker_image: + name: Build Docker image + runs-on: ubuntu-latest + needs: [quality, test, build_docker_image_set_env] + + steps: + # Due to an issue with checking out a wrong commit, we make sure + # to checkout HEAD commit for a pull request. + # More details: https://github.com/actions/checkout/issues/299 + - name: Checkout pull request HEAD commit instead of merge commit 🕝 + uses: actions/checkout@v2 + if: github.event_name == 'pull_request' + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Checkout git repository 🕝 + uses: actions/checkout@v2 + if: github.event_name != 'pull_request' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@154c24e1f33dbb5865a021c99f1318cfebf27b32 + with: + version: latest + + - name: Set environment variables + run: | + echo "IMAGE_TAG=${{ needs.build_docker_image_set_env.outputs.image_tag }}" >> $GITHUB_ENV + + - name: Build Docker image + run: | + docker buildx bake --load + deploy: name: Deploy to PyPI runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index a6e5cfb9f..6cb470877 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,25 @@ -FROM python:3.7-slim as python_builder -RUN apt-get update -qq && \ - apt-get install -y --no-install-recommends \ - build-essential \ - curl +FROM ubuntu:20.04 as base + +RUN apt-get update -qq \ + && apt-get install -y --no-install-recommends \ + python3 \ + python3-venv \ + python3-pip \ + python3-dev \ + && apt-get autoremove -y + +# Make sure that all security updates are installed +RUN apt-get update && apt-get dist-upgrade -y --no-install-recommends && apt-get autoremove -y + +RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 100 \ + && update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 100 + +FROM base as python_builder + +RUN apt-get update -qq \ + && apt-get install -y --no-install-recommends \ + curl \ + && apt-get autoremove -y # install poetry # keep this in sync with the version in pyproject.toml and Dockerfile @@ -12,18 +29,41 @@ ENV PATH "/root/.poetry/bin:/opt/venv/bin:${PATH}" # install dependencies COPY . /app/ + +WORKDIR /app + RUN python -m venv /opt/venv && \ . /opt/venv/bin/activate && \ pip install --no-cache-dir -U pip && \ - cd /app && \ - poetry install --no-dev --no-interaction + pip install wheel && \ + poetry install --no-dev --no-root --no-interaction + +# install rasa-sdk and build wheels +RUN . /opt/venv/bin/activate && poetry build -f wheel -n \ + && pip install --no-deps dist/*.whl \ + && mkdir /wheels \ + && poetry export -f requirements.txt --without-hashes > /wheels/requirements.txt \ + && poetry run pip wheel --wheel-dir=/wheels -r /wheels/requirements.txt \ + && find /app/dist -maxdepth 1 -mindepth 1 -name '*.whl' -print0 | xargs -0 -I {} mv {} /wheels/ # start a new build stage -FROM python:3.7-slim +FROM base + +# copy needed files +COPY ./poetry.lock /app/ +COPY ./entrypoint.sh /app/ +COPY --from=python_builder /wheels /wheels + +# pip install & make directories +RUN cd /wheels; ls -1 *.whl | awk -F - '{ gsub("_", "-", $1); print $1 }' | uniq > /wheels/requirements.txt \ + && python -m venv /opt/venv \ + && . /opt/venv/bin/activate \ + && pip install --no-cache-dir -U pip \ + && pip install --no-index --find-links=/wheels -r /wheels/requirements.txt \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ + && rm -rf /wheels \ + && rm -rf /root/.cache/pip/* -# copy everything from /opt -COPY --from=python_builder /opt/venv /opt/venv -COPY --from=python_builder /app /app ENV PATH="/opt/venv/bin:$PATH" # update permissions & change user diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 000000000..dfd5e97c7 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,12 @@ +variable "IMAGE_NAME" { + default = "rasa/rasa-sdk" +} + +variable "IMAGE_TAG" { + default = "main" +} + +target "default" { + dockerfile = "./Dockerfile" + tags = ["${IMAGE_NAME}:${IMAGE_TAG}"] +}