Skip to content

Commit 43a37f0

Browse files
committed
Prepare for deployment
1 parent 30e5a96 commit 43a37f0

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed

.github/workflows/ci.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,32 @@ jobs:
5555
tox-envs: "py,coverage-report,typing"
5656
tox-requirements: "requirements/tox.txt"
5757

58+
build:
59+
runs-on: ubuntu-latest
60+
needs: [lint, test]
61+
timeout-minutes: 10
62+
63+
# Only do Docker builds of tagged releases and pull requests from ticket
64+
# branches. This will still trigger on pull requests from untrusted
65+
# repositories whose branch names match our tickets/* branch convention,
66+
# but in this case the build will fail with an error since the secret
67+
# won't be set.
68+
if: >
69+
startsWith(github.ref, 'refs/tags/')
70+
|| startsWith(github.head_ref, 'tickets/')
71+
72+
steps:
73+
- uses: actions/checkout@v4
74+
with:
75+
fetch-depth: 0
76+
77+
- uses: lsst-sqre/build-and-push-to-ghcr@v1
78+
id: build
79+
with:
80+
image: ${{ github.repository }}
81+
# TODO: set token
82+
github_token: ${{ secrets.GITHUB_TOKEN }}
83+
5884
docs:
5985

6086
runs-on: ubuntu-latest

Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# This Dockerfile has three stages:
2+
#
3+
# base-image
4+
# Updates the base Python image with security patches and common system
5+
# packages. This image becomes the base of all other images.
6+
# install-image
7+
# Installs third-party dependencies (requirements/main.txt) and the
8+
# application into a virtual environment. This virtual environment is
9+
# ideal for copying across build stages.
10+
# runtime-image
11+
# - Copies the virtual environment into place.
12+
# - Runs a non-root user.
13+
# - Sets up the entrypoint and port.
14+
15+
FROM python:3.12.4-slim-bookworm as base-image
16+
17+
# Update system packages
18+
COPY scripts/install-base-packages.sh .
19+
RUN ./install-base-packages.sh && rm ./install-base-packages.sh
20+
21+
FROM base-image AS install-image
22+
23+
# Install system packages only needed for building dependencies.
24+
COPY scripts/install-dependency-packages.sh .
25+
RUN ./install-dependency-packages.sh
26+
27+
# Create a Python virtual environment
28+
ENV VIRTUAL_ENV=/opt/venv
29+
RUN python -m venv $VIRTUAL_ENV
30+
31+
# Make sure we use the virtualenv
32+
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
33+
34+
# Put the latest pip and setuptools in the virtualenv
35+
RUN pip install --upgrade --no-cache-dir pip setuptools wheel
36+
37+
# Install the app's Python runtime dependencies
38+
COPY requirements/main.txt ./requirements.txt
39+
RUN pip install --quiet --no-cache-dir -r requirements.txt
40+
41+
# Install the application.
42+
COPY . /workdir
43+
WORKDIR /workdir
44+
RUN pip install --no-cache-dir .
45+
46+
FROM base-image AS runtime-image
47+
48+
# Create a non-root user.
49+
RUN useradd --create-home appuser
50+
51+
# Copy the virtualenv.
52+
COPY --from=install-image /opt/venv /opt/venv
53+
54+
# Make sure we use the virtualenv.
55+
ENV PATH="/opt/venv/bin:$PATH"
56+
57+
# Switch to the non-root user.
58+
USER appuser
59+
60+
# Expose the port.
61+
EXPOSE 8080
62+
63+
# Run the application.
64+
CMD ["sasquatchbackpack", "usgs-earthquake-data", "-d", "10", "0"]

scripts/docker-tag.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
# Determine the tag for Docker images based on GitHub Actions environment
4+
# variables.
5+
6+
set -eo pipefail
7+
8+
if [ -n "$GITHUB_HEAD_REF" ]; then
9+
# For pull requests
10+
echo ${GITHUB_HEAD_REF} | sed -E 's,/,-,g'
11+
else
12+
# For push events
13+
echo ${GITHUB_REF} | sed -E 's,refs/(heads|tags)/,,' | sed -E 's,/,-,g'
14+
fi

scripts/install-base-packages.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
3+
# This script updates packages in the base Docker image that's used by both
4+
# the build and runtime images, and gives us a place to install additional
5+
# system-level packages with apt-get.
6+
#
7+
# Based on the blog post:
8+
# https://pythonspeed.com/articles/system-packages-docker/
9+
10+
# Bash "strict mode", to help catch problems and bugs in the shell
11+
# script. Every bash script you write should include this. See
12+
# http://redsymbol.net/articles/unofficial-bash-strict-mode/ for details.
13+
set -euo pipefail
14+
15+
# Display each command as it's run.
16+
set -x
17+
18+
# Tell apt-get we're never going to be able to give manual feedback.
19+
export DEBIAN_FRONTEND=noninteractive
20+
21+
# Update the package listing, so we know what packages exist.
22+
apt-get update
23+
24+
# Install security updates.
25+
apt-get -y upgrade
26+
27+
# Install dependencies required at runtime. git is used to check out notebook
28+
# repositories. git-lfs is required to check the Git LFS service.
29+
apt-get -y install --no-install-recommends git git-lfs
30+
31+
# Delete cached files we don't need anymore.
32+
apt-get clean
33+
rm -rf /var/lib/apt/lists/*
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
3+
# This script installs additional packages used by the dependency image but
4+
# not needed by the runtime image, such as additional packages required to
5+
# build Python dependencies.
6+
#
7+
# Since the base image wipes all the apt caches to clean up the image that
8+
# will be reused by the runtime image, we unfortunately have to do another
9+
# apt-get update here, which wastes some time and network.
10+
11+
# Bash "strict mode", to help catch problems and bugs in the shell
12+
# script. Every bash script you write should include this. See
13+
# http://redsymbol.net/articles/unofficial-bash-strict-mode/ for details.
14+
set -euo pipefail
15+
16+
# Display each command as it's run.
17+
set -x
18+
19+
# Tell apt-get we're never going to be able to give manual feedback.
20+
export DEBIAN_FRONTEND=noninteractive
21+
22+
# Update the package listing, so we know what packages exist.
23+
apt-get update
24+
25+
# Install various dependencies that may be required to install mobu:
26+
#
27+
# build-essential: sometimes needed to build Python modules
28+
# libffi-dev: sometimes needed to build cffi, a cryptography dependency
29+
apt-get -y install --no-install-recommends build-essential libffi-dev
30+
31+
# Delete cached files we don't need anymore.
32+
apt-get clean
33+
rm -rf /var/lib/apt/lists/*

0 commit comments

Comments
 (0)