Home > Net >  How to publish changes to Docker images using Github Actions
How to publish changes to Docker images using Github Actions

Time:12-23

I am working on a CI/CD pipeline using Docker and GitHub Packages/Actions. I have 2 workflows: build.yml and deploy.yml.

The build.yml workflow is supposed to pull the Docker images from GitHub Packages, build them, run automated tests, then push the new images to GitHub Packages.

The deploy.yml workflow pulls the images to the server and runs them.

The issue I am having is that my local changes are not being updated on the server.

build.yml:

name: Build and Test

on:
  push:
    branches:
      - development

env:
  BACKEND_IMAGE: ghcr.io/$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')/backend
  FRONTEND_IMAGE: ghcr.io/$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')/frontend
  NGINX_IMAGE: ghcr.io/$(echo $GITHUB_REPOSITORY | tr '[:upper:]' '[:lower:]')/nginx

jobs:
  test:
    name: Build Images and Run Automated Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout master
        uses: actions/checkout@v1
      - name: Add environment variables to .env
        run: |
          echo DEBUG=0 >> .env
          echo SQL_ENGINE=django.db.backends.postgresql >> .env
          echo DATABASE=postgres >> .env
          echo SECRET_KEY=${{ secrets.SECRET_KEY }} >> .env
          echo SQL_DATABASE=${{ secrets.SQL_DATABASE }} >> .env
          echo SQL_USER=${{ secrets.SQL_USER }} >> .env
          echo SQL_PASSWORD=${{ secrets.SQL_PASSWORD }} >> .env
          echo SQL_HOST=${{ secrets.SQL_HOST }} >> .env
          echo SQL_PORT=${{ secrets.SQL_PORT }} >> .env
      - name: Set environment variables
        run: |
          echo "BACKEND_IMAGE=$(echo ${{env.BACKEND_IMAGE}} )" >> $GITHUB_ENV
          echo "FRONTEND_IMAGE=$(echo ${{env.FRONTEND_IMAGE}} )" >> $GITHUB_ENV
          echo "NGINX_IMAGE=$(echo ${{env.NGINX_IMAGE}} )" >> $GITHUB_ENV
      - name: Log in to GitHub Packages
        run: echo ${PERSONAL_ACCESS_TOKEN} | docker login ghcr.io -u ${{ secrets.NAMESPACE }} --password-stdin
        env:
          PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      - name: Pull images
        run: |
          docker pull ${{ env.BACKEND_IMAGE }} || true
          docker pull ${{ env.FRONTEND_IMAGE }} || true
          docker pull ${{ env.NGINX_IMAGE }} || true
      - name: Build images
        run: |
          docker-compose -f docker-compose.ci.yml build
      - name: Run Backend Tests
        run: |
          docker-compose -f docker-compose.ci.yml run backend python manage.py test
      - name: Push images
        run: |
          docker push ${{ env.BACKEND_IMAGE }}
          docker push ${{ env.FRONTEND_IMAGE }}
          docker push ${{ env.NGINX_IMAGE }}

docker-compose.ci.yml:

version: "3.8"

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
    command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - ./backend:/backend
      - static_volume:/static
      - media_volume:/media
    expose:
      - 8000
    env_file: .env
  frontend:
    build:
      context: ./frontend
    volumes:
      - frontend_build:/frontend/build
  nginx:
    build:
      context: ./nginx
    ports:
      - 80:80
    volumes:
      - frontend_build:/var/www/frontend
    depends_on:
      - backend
      - frontend

volumes:
  frontend_build:
  static_volume:
  media_volume:

backend/Dockerfile.prod:

FROM python:3.9.5-alpine
WORKDIR /backend
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN apk update \
    && apk add --virtual build-deps gcc python3-dev musl-dev \
    && apk add postgresql-dev \
    && pip install psycopg2 \
    && apk del build-deps
RUN pip install --upgrade pip
COPY ./requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
COPY ./entrypoint.prod.sh /entrypoint.prod.sh
COPY . /backend/
ENTRYPOINT ["/entrypoint.prod.sh"]

I have tried a few different things to no avail. Any help understanding why my changes are not updating would be appreciated!

CodePudding user response:

It seems like you are re-pushing the same images you pulled instead of the images built. In order to validate that, you can remove the Pull images step to confirm that.

If that is the case you can either change the way you tag the images in docker-compose.ci.yml or change the images you push in the Push images step.

Alternatively, you can use the flow documented here with minor changes:

name: Create and publish a Docker image

on:
  push:
    branches: ['release']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Log in to the Container registry
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and push backend Docker image
        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
        with:
          context: ./backend # <<<=== Notice this
          file: Dockerfile.prod # <<<=== Notice this
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

Add another Dockerfile for the frontend and duplicate the last step for it.

  • Related