From 1406f135e5946105f8ec8d668e3f05f065f78dcc Mon Sep 17 00:00:00 2001 From: Lance Albertson Date: Mon, 24 Jun 2024 14:43:20 -0700 Subject: [PATCH] Dockerize prerelease website (#66) This will allow the OSL to manage this as a docker container and handle updates better in the long term. Some key changes: - Add weekly dependabot checks - Add requirements.txt - Add basic CI - Build and release container images on ghcr.io which will be used in the cookbook - Do a weekly build regardless of any dependabot bumps - Deploy website using gunicorn instead of mod_python - Create wsgi.py for gunicorn Signed-off-by: Lance Albertson --- .github/dependabot.yml | 7 ++++ .github/workflows/bootstrap.yml | 11 ------- .github/workflows/ci.yml | 22 +++++++++++++ .github/workflows/container.yml | 57 +++++++++++++++++++++++++++++++++ Dockerfile | 8 +++++ entrypoint.sh | 12 +++++++ requirements.txt | 23 +++++++++++++ wsgi.py | 4 +++ 8 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/bootstrap.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/container.yml create mode 100644 Dockerfile create mode 100755 entrypoint.sh create mode 100644 requirements.txt create mode 100644 wsgi.py diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..4c6621f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +--- +version: 2 +updates: + - package-ecosystem: pip + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/bootstrap.yml b/.github/workflows/bootstrap.yml deleted file mode 100644 index cc5c17d..0000000 --- a/.github/workflows/bootstrap.yml +++ /dev/null @@ -1,11 +0,0 @@ -on: - workflow_dispatch: - - -jobs: - bootstrap: - runs-on: ubuntu-22.04 - steps: - - name: helloworld - run: | - echo "Hello World" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a6576ab --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,22 @@ +--- +name: Build and install python packages +on: [push] +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.11" + - "3.12" + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 0000000..23f807c --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,57 @@ +--- +name: Create and publish a Docker image + +on: + push: + branches: + - master + pull_request: + schedule: + - cron: '45 18 * * 3' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + docker: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and export Docker image + uses: docker/build-push-action@v5 + with: + context: . + tags: ros-infrastructure/prerelease_website:test + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Log in to the Container registry + if: contains(fromJSON('["push", "schedule"]'), github.event_name) + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + if: contains(fromJSON('["push", "schedule"]'), github.event_name) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=schedule,${{ github.ref_name }} + - name: Build and push Docker image + if: contains(fromJSON('["push", "schedule"]'), github.event_name) + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9edd019 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM python:3.11-alpine + +COPY requirements.txt /prerelease_website/requirements.txt +WORKDIR /prerelease_website +RUN pip --no-cache-dir install -r requirements.txt +COPY . /prerelease_website +ENTRYPOINT ["/prerelease_website/entrypoint.sh"] +EXPOSE 5000 diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..1b5cad0 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +exec gunicorn \ + -u nobody \ + -g nobody \ + --access-logfile '-' \ + --error-logfile '-' \ + --log-file "-" \ + --access-logformat '%({x-forwarded-for}i)s %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' \ + --forwarded-allow-ips="140.211.9.104,2605:bc80:3010:104::8cd3:968" \ + -w 4 \ + -b 0.0.0.0:5000 \ + 'wsgi:app' diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e511d5a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,23 @@ +blinker==1.8.2 +catkin-pkg==1.0.0 +click==8.1.7 +configparser==7.0.0 +distro==1.9.0 +docutils==0.21.2 +empy==4.1 +Flask==3.0.3 +gunicorn==22.0.0 +itsdangerous==2.2.0 +Jinja2==3.1.4 +MarkupSafe==2.1.5 +packaging==24.1 +pyparsing==3.1.2 +python-dateutil==2.9.0.post0 +PyYAML==6.0.1 +ros-buildfarm==3.0.0 +rosdistro==0.9.1 +rosinstall-generator==0.1.23 +rospkg==1.5.1 +six==1.16.0 +vcstool==0.3.0 +Werkzeug==3.0.3 diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..f878fd9 --- /dev/null +++ b/wsgi.py @@ -0,0 +1,4 @@ +from prerelease_website import app + +if __name__ == "__main__": + app.run()