Skip to content

Commit

Permalink
Merge pull request #8706 from cfpb/feature/deployable-zipfile-images
Browse files Browse the repository at this point in the history
Better building and testing of deployable zipfile artifacts
  • Loading branch information
chosak authored Jan 8, 2025
2 parents 55b1315 + cee8489 commit 181307b
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 99 deletions.
53 changes: 40 additions & 13 deletions .github/workflows/build-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ on:

jobs:
Build:
if: "! github.event.pull_request.head.repo.fork"
runs-on: ubuntu-latest
env:
ARTIFACT_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
Expand All @@ -20,25 +19,53 @@ jobs:
with:
node-version: '20.x'

- name: Install Act dependencies (if needed)
if: ${{ env.ACT }}
run: corepack enable

- name: Install dependencies
run: yarn

- name: Build frontend
run: yarn run build

- name: Run the build process with Docker
uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
image: ghcr.io/${{ github.repository }}-builder:main
options: -v ${{ github.workspace }}:/cfgov
run: |
source scl_source enable rh-python38
./call_create.sh
- name: Upload arifact
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Pull image to build artifact
run: docker pull ghcr.io/cfpb/cfgov-artifact-builder:latest

- name: Build artifact
run: |
docker run \
-v `pwd`:/cfgov \
ghcr.io/cfpb/cfgov-artifact-builder:latest
- name: Pull image to test artifact
run: docker pull ghcr.io/cfpb/cfgov-artifact-tester:latest

- name: Run built artifact as a Docker container
run: |
docker run \
--name cfgov \
-d \
-v `pwd`:/cfgov:ro \
-p 8000:80 \
--env-file docker/centos7/test.env \
ghcr.io/cfpb/cfgov-artifact-tester:latest
- name: Wait for artifact container to be ready
run: |
timeout 180s bash -c \
'until [ "$(docker inspect -f {{.State.Health.Status}} cfgov)" == "healthy" ]; do sleep 2; done'
# Don't upload artifacts to S3 if PR is against a fork.
- name: Upload artifact to S3
if: "! github.event.pull_request.head.repo.fork"
uses: keithweaver/[email protected]
with:
command: cp
Expand Down
41 changes: 22 additions & 19 deletions .github/workflows/builder.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
name: Create and publish a Docker image that can be used to build a deployable zipfile
name: Maintain deployable zipfile Docker images

on:
push:
branches: ['main']
paths:
- 'docker/builder/**'

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}-builder
- 'docker/centos7/**'
workflow_dispatch:

jobs:
build-and-push-image:
Expand All @@ -25,20 +22,26 @@ jobs:
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build deployable zipfile builder image
run: |
docker build docker/centos7 \
--target=cfgov-artifact-builder \
-t ghcr.io/cfpb/cfgov-artifact-builder:latest
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./docker/builder/
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Build deployable zipfile tester image
run: |
docker build docker/centos7 \
--target=cfgov-artifact-tester \
-t ghcr.io/cfpb/cfgov-artifact-tester:latest
- name: Push deployable zipfile builder image
run: |
docker push ghcr.io/cfpb/cfgov-artifact-builder:latest
- name: Push deployable zipfile tester image
run: |
docker push ghcr.io/cfpb/cfgov-artifact-tester:latest
30 changes: 0 additions & 30 deletions docker/builder/Dockerfile

This file was deleted.

7 changes: 0 additions & 7 deletions docker/builder/docker-entrypoint.sh

This file was deleted.

37 changes: 37 additions & 0 deletions docker/centos7/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM centos:7 AS centos7-py38

COPY ./fix_centos_repos.sh .

RUN \
./fix_centos_repos.sh && \
yum update -y && \
yum install -y centos-release-scl && \
./fix_centos_repos.sh && \
yum install -y rh-python38

FROM centos7-py38 AS cfgov-artifact-builder

RUN \
yum install -y gcc && \
source /opt/rh/rh-python38/enable && \
pip install --no-cache-dir -U pip setuptools wheel

COPY ./build_cfgov_artifact.sh .

ENTRYPOINT ["./build_cfgov_artifact.sh"]

FROM centos7-py38 AS cfgov-artifact-tester

RUN yum install -y httpd24 rh-python38-mod_wsgi && \
source /opt/rh/rh-python38/enable && \
pip install --no-cache-dir virtualenv

COPY ./install_cfgov_and_run_apache.sh .

EXPOSE 80

HEALTHCHECK \
--start-period=60s \
CMD curl -f http://localhost/ || exit 1

ENTRYPOINT ["./install_cfgov_and_run_apache.sh"]
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ build_args=(
"--extra-static" "$webfonts_path"
)

# Activate the appropriate version of Python.
source /opt/rh/rh-python38/enable

# Build the deployable zipfile.
"$cfgov_refresh_volume/cfgov/deployable_zipfile/create.py" "${build_args[@]}"

Expand Down
11 changes: 11 additions & 0 deletions docker/centos7/fix_centos_repos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh

set -e

# As CentOS is now EOL, certain package URLs no longer resolve properly.
# Run this script prior to "yum install".
# See https://serverfault.com/q/1161816.

sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/CentOS-*.repo
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/CentOS-*.repo
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/CentOS-*.repo
72 changes: 72 additions & 0 deletions docker/centos7/install_cfgov_and_run_apache.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash

# Fail when any command fails.
set -e

build_artifact="/cfgov/cfgov_current_build.zip"
cfgov_root=/srv/cfgov
install_location="$cfgov_root/current"
cfgov_environ="$install_location/environment.json"
cfgov_httpd="$install_location/cfgov/apache"
system_httpd=/opt/rh/httpd24

# Verify that the artifact is where we expect it to be.
if [[ ! -e "$build_artifact" ]]; then
echo "Build artifact $build_artifact does not exist." >&2
echo "Did you forget to mount the Docker volume?" >&2
exit 1
fi

# Create directory for unpacked artifact.
mkdir -p "$install_location"

# Create staticfiles directory.
# TODO: Remove along with Apache conf, this is no longer used.
mkdir -p "$cfgov_root/static"

# Activate the appropriate version of Python and unpack the artifact.
. /opt/rh/rh-python38/enable
python "$build_artifact" -d "$install_location"

# Patch SQLite with a newer version.
# The version that comes with CentOS 7/Python 3.8 is 3.7.17.
# As of Django 2.2, the minimum supported SQLite version is 3.8.3:
# https://docs.djangoproject.com/en/2.2/releases/2.2/#miscellaneous
# This hack patches Python to use the newer pysqlite3 version instead.
"$install_location/venv/bin/pip" install --no-cache-dir pysqlite3-binary
echo \
'import pysqlite3;'\
'import sys;' \
'sys.modules["sqlite3"] = sys.modules.pop("pysqlite3")' > \
"$install_location/venv/lib/python3.8/site-packages/patch_sqlite.pth"

# Create Django environment JSON file from the environment.
echo "{" > "$cfgov_environ"
env | sort | sed 's/\(.*\)=\(.*\)/ "\1": "\2",/' >> "$cfgov_environ"
sed -i '$ s/,$/\n}/' "$cfgov_environ"

# Collect Django static files.
"$install_location/venv/bin/django-admin" collectstatic --noinput

# Migrate and populate the Django database.
"$install_location/venv/bin/django-admin" migrate --noinput
"$install_location/venv/bin/django-admin" createcachetable
"$install_location/venv/bin/django-admin" runscript initial_data

# Create necessary Apache symlinks.
for symlink in modules run; do
ln -s "$system_httpd/root/etc/httpd/$symlink" "$cfgov_httpd/$symlink"
done
ln -s "$cfgov_httpd/conf.d/wsgi.conf.venv" "$cfgov_httpd/conf.d/wsgi.conf"

# Give the Apache user permission to read the unpacked files.
chown -R "$APACHE_USER":"$APACHE_GROUP" "$cfgov_root"

# Run Apache the way the systemd service would.
# See /usr/lib/systemd/system/httpd24-httpd.service.
. "$system_httpd/enable"
set -a
. "$system_httpd/root/etc/sysconfig/httpd"
"$system_httpd/root/usr/sbin/httpd" \
-f /srv/cfgov/current/cfgov/apache/conf/httpd.conf \
-DFOREGROUND
23 changes: 23 additions & 0 deletions docker/centos7/test.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Apache variables
CFGOV_PATH=/srv/cfgov
CFGOV_CURRENT=/srv/cfgov/current
STATIC_PATH=/srv/cfgov/static
APACHE_SERVER_ROOT=/srv/cfgov/current/cfgov/apache
APACHE_PROCESS_COUNT=4
ERROR_LOG=/dev/stderr
ACCESS_LOG=/dev/stdout
SCL_PYTHON_VERSION=rh-python38
APACHE_UPLOADS_F_ALIAS=https://files.consumerfinance.gov/f/
APACHE_HTTPS_FORWARDED_HOST=
APACHE_PORT=80
LIMIT_REQUEST_BODY=0
APACHE_STATUS_ALLOW_FROM=127.0.0.1 ::1 localhost
APACHE_USER=apache
APACHE_GROUP=apache
CFGOV_APPLICATION_HOST=

# Django variables
ALLOWED_HOSTS=[\"*\"]
DATABASE_URL=sqlite:////srv/cfgov/current/test.sqlite
DJANGO_SETTINGS_MODULE=cfgov.settings.production
SECRET_KEY=testing
Loading

0 comments on commit 181307b

Please sign in to comment.