From ccb11470f89fc31021a8f27e55e42781da9079fb Mon Sep 17 00:00:00 2001 From: Muhammad Farhan <129956601+mfarhan943@users.noreply.github.com> Date: Tue, 22 Oct 2024 18:58:44 +0500 Subject: [PATCH] feat: Add workflow and Dockerfile for Course Discovery (#41) --- .../push-course-discovery-image.yaml | 58 ++++++++++ dockerfiles/course-discovery.Dockerfile | 106 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 .github/workflows/push-course-discovery-image.yaml create mode 100644 dockerfiles/course-discovery.Dockerfile diff --git a/.github/workflows/push-course-discovery-image.yaml b/.github/workflows/push-course-discovery-image.yaml new file mode 100644 index 0000000..4805065 --- /dev/null +++ b/.github/workflows/push-course-discovery-image.yaml @@ -0,0 +1,58 @@ +name: Build and Push Course Discovery Image + +on: + workflow_dispatch: + inputs: + branch: + description: "Target branch from which the source dockerfile from image will be sourced" + + schedule: + - cron: "0 4 * * 1-5" # UTC Time + +jobs: + build-and-push-image: + runs-on: ubuntu-22.04 + + steps: + - name: Get tag name + id: get-tag-name + uses: actions/github-script@v5 + with: + script: | + const tagName = "${{ github.event.inputs.branch }}" || 'latest'; + return tagName; + result-encoding: string + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Build and push Dev Docker image + uses: docker/build-push-action@v6 + with: + file: ./dockerfiles/course-discovery.Dockerfile + push: true + target: dev + tags: edxops/discovery-dev:${{ steps.get-tag-name.outputs.result }} + platforms: linux/amd64,linux/arm64 + + - name: Send failure notification + if: failure() + uses: dawidd6/action-send-mail@v3 + with: + server_address: email-smtp.us-east-1.amazonaws.com + server_port: 465 + username: ${{secrets.edx_smtp_username}} + password: ${{secrets.edx_smtp_password}} + subject: Push Image to docker.io/edxops failed in Course Discovery + to: phoenix@2u.com + from: github-actions + body: Push Image to docker.io/edxops for Course Discovery failed! For details see "github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" diff --git a/dockerfiles/course-discovery.Dockerfile b/dockerfiles/course-discovery.Dockerfile new file mode 100644 index 0000000..89a1709 --- /dev/null +++ b/dockerfiles/course-discovery.Dockerfile @@ -0,0 +1,106 @@ +FROM ubuntu:focal as app + +ARG PYTHON_VERSION=3.12 + +ENV DEBIAN_FRONTEND noninteractive +ENV TZ=UTC + +# System requirements. +RUN apt-get update && \ + apt-get install -y software-properties-common && \ + apt-add-repository -y ppa:deadsnakes/ppa && \ + apt-get install -qy \ + curl \ + gettext \ + # required by bower installer + git \ + language-pack-en \ + build-essential \ + libmysqlclient-dev \ + libssl-dev \ + # TODO: Current version of Pillow (9.5.0) doesn't provide pre-built wheel for python 3.12, + # So this apt package is needed for building Pillow on 3.12, + # and can be removed when version of Pillow is upgraded to 10.5.0+ + libjpeg-dev \ + # mysqlclient >= 2.2.0 requires pkg-config. + pkg-config \ + libcairo2-dev \ + python3-pip \ + python${PYTHON_VERSION} \ + python${PYTHON_VERSION}-dev \ + python${PYTHON_VERSION}-distutils && \ + rm -rf /var/lib/apt/lists/* + +# Use UTF-8. +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +ARG COMMON_APP_DIR="/edx/app" +ARG COMMON_CFG_DIR="/edx/etc" +ARG DISCOVERY_SERVICE_NAME="discovery" +ARG DISCOVERY_APP_DIR="${COMMON_APP_DIR}/${DISCOVERY_SERVICE_NAME}" +ARG DISCOVERY_VENV_DIR="${COMMON_APP_DIR}/${DISCOVERY_SERVICE_NAME}/venvs/${DISCOVERY_SERVICE_NAME}" +ARG DISCOVERY_CODE_DIR="${DISCOVERY_APP_DIR}/${DISCOVERY_SERVICE_NAME}" +ARG DISCOVERY_NODEENV_DIR="${DISCOVERY_APP_DIR}/nodeenvs/${DISCOVERY_SERVICE_NAME}" + +ENV PATH "${DISCOVERY_VENV_DIR}/bin:${DISCOVERY_NODEENV_DIR}/bin:$PATH" +ENV DISCOVERY_CFG "/edx/etc/discovery.yml" +ENV DISCOVERY_CODE_DIR "${DISCOVERY_CODE_DIR}" +ENV DISCOVERY_APP_DIR "${DISCOVERY_APP_DIR}" +ENV PYTHON_VERSION "${PYTHON_VERSION}" + +# Setup zoneinfo for Python 3.12 +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python${PYTHON_VERSION} +RUN pip install virtualenv + +RUN virtualenv -p python${PYTHON_VERSION} --always-copy ${DISCOVERY_VENV_DIR} + +# No need to activate discovery venv as it is already in path +RUN pip install nodeenv + +RUN nodeenv ${DISCOVERY_NODEENV_DIR} --node=16.14.0 --prebuilt && npm install -g npm@8.5.x + +# Working directory will be root of repo. +WORKDIR ${DISCOVERY_CODE_DIR} + +# Cloning git repo +RUN curl -L https://github.com/openedx/course-discovery/archive/refs/heads/master.tar.gz | tar -xz --strip-components=1 + +RUN npm install --production && ./node_modules/.bin/bower install --allow-root --production && ./node_modules/.bin/webpack --config webpack.config.js --progress + +# Expose canonical Discovery port +EXPOSE 8381 + +FROM app as prod + +ENV DJANGO_SETTINGS_MODULE "course_discovery.settings.production" + +RUN pip install -r ${DISCOVERY_CODE_DIR}/requirements/production.txt + +RUN DISCOVERY_CFG=minimal.yml OPENEDX_ATLAS_PULL=true make pull_translations + +CMD gunicorn --bind=0.0.0.0:8381 --workers 2 --max-requests=1000 -c course_discovery/docker_gunicorn_configuration.py course_discovery.wsgi:application + +FROM app as dev + +ENV DJANGO_SETTINGS_MODULE "course_discovery.settings.devstack" + +RUN pip install -r ${DISCOVERY_CODE_DIR}/requirements/django.txt +RUN pip install -r ${DISCOVERY_CODE_DIR}/requirements/local.txt + +RUN DISCOVERY_CFG=minimal.yml OPENEDX_ATLAS_PULL=true make pull_translations + +# Devstack related step for backwards compatibility +RUN touch ${DISCOVERY_APP_DIR}/discovery_env + +CMD while true; do python ./manage.py runserver 0.0.0.0:8381; sleep 2; done + +########################################################### +# Define k8s target +FROM prod as kubernetes +ENV DISCOVERY_SETTINGS='kubernetes' +ENV DJANGO_SETTINGS_MODULE="course_discovery.settings.$DISCOVERY_SETTINGS"