Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Docker image build #17

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Add Docker image build #17

wants to merge 5 commits into from

Conversation

hbruch
Copy link
Collaborator

@hbruch hbruch commented Feb 3, 2024

This PR adds a Dockerfile and an action to build a docker image for the master branches.

Copy link

@derhuerst derhuerst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a typo in entrypoint.sh which doesn't cause it to fail because it doesn't run set -u.

Dockerfile Outdated
@@ -0,0 +1,21 @@
FROM python:3.11

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest using a slim base image, it has the same glibc-based environment, but includes less irrelevant tools out-of-the-box (~160mb vs 1gb).

Suggested change
FROM python:3.11
FROM python:3.11-slim

Also, is there a reason why we don't use Python v3.12, given that the CI runs tests for it?

Dockerfile Outdated

ENV RUN_MIGRATION=false

RUN apt-get install

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this command do?

@@ -0,0 +1,16 @@
cd web

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script won't abort when commands fail and with unbound (a.k.a. undefined) variables (as with the typo below). However, given that some operating systems' sh shells seem to not support set -o pipefail yes, even though it should be supported everywhere, I suggest using bash instead.

Also, add a shebang, to avoid confusion about which shell to run this file with.

Suggested change
cd web
#!/bin/bash
set -eu -o pipefail
cd web

entrypoint.sh Outdated
cd web

# Run migration only if explicitly set via ENV
if [ "$RUN_MIGRATION" != "false" ]; then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to make this case opt-in, why not check for "$RUN_MIGRATION" = "true"?

entrypoint.sh Outdated
./manage.py migrate
fi

if [ "$ASSING_LOCATIONS" != "false" ]; then

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if [ "$ASSING_LOCATIONS" != "false" ]; then
if [ "$ASSIGN_LOCATIONS" != "false" ]; then

entrypoint.sh Outdated
fi

# don't create an admin interface per default
#./manage.py createsuperuser

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we put this behind an opt-in env var as well?

Dockerfile Outdated

RUN apt-get install
RUN apt-get update && apt-get install -y \
libpq-dev libgdal-dev libproj-dev libgeos-dev \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to apt, this installs 824mb worth of packages. Even with --no-install-recommends, it is still 641mb.

Are these dependencies build dependencies (in contrast to runtime dependencies)? Then I suggest adding a build step and copying the build output only.

#./manage.py createsuperuser

# start the server
./manage.py $@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to use exec here.

[…] If we call prog1 -> prog2 -> prog3 -> prog4 etc. and never go back, then make each call an exec. It saves resources (not much, admittedly, unless repeated) and makes shutdown simplier.

StackOverflow explainer about exec's purposes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After entrypoint.sh is run, the container CMD should be executed. IMHO exec would prevent this(?)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have a misunderstanding here. I referred to the exec Bash built-in. How would it prevent running the command specified in CMD?

Dockerfile Outdated

RUN apt-get install
RUN apt-get update && apt-get install -y \
libpq-dev libgdal-dev libproj-dev libgeos-dev \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
libpq-dev libgdal-dev libproj-dev libgeos-dev \
git \
libpq-dev libgdal-dev libproj-dev libgeos-dev \

i.e.
* switch to prebuilt gdal image
* multistaged docker build
* allow superuser creation via flag
* use bash for script execution
* set -euo pipefial for entrypoint.sh
@@ -0,0 +1,34 @@
FROM ghcr.io/osgeo/gdal:alpine-small-3.9.2 AS builder

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a "floating tag", but hard-codes as specific set of libraries, which means that we won't get security patches "automatically" with a rebuild. We should make sure that there is a tool like Mend Renovate (bot) that notifies about updates to this image.

file: Dockerfile
push: true
tags: |
ghcr.io/${{ steps.lower-repo.outputs.lowercase }}:latest,ghcr.io/${{ steps.lower-repo.outputs.lowercase }}:${{ steps.version.outputs.builddate }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will create an image named parkendd/parkapi2, where as ParkAPI v3 images are named parkendd/park-api-v3. Do we want to align the v2 naming scheme with the v3 one?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the CI is configured right now, the image will not have (meaningful) OCI annotations, except the (deprecated) plain maintainer label in Dockerfile.

I suggest adding helpful OCI annotations like org.opencontainers.image.source (to find the underlying Git repo) or org.opencontainers.image.licenses (to quickly find out ParkAPI2's license(s)), either


- name: lowercase repo name
id: lower-repo
uses: ASzc/change-string-case-action@v6

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like relying on this unpinned "random" third-party dependency is not necessary because there are various built-in utilities to lower-case a string.

Suggested change
uses: ASzc/change-string-case-action@v6
run: |
echo "lowercase=$(echo -n '${{ github.repository }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT


cd web
if [ "$RUN_MIGRATION" -eq "1" ]; then
echo "RUN MIGRATION is TRUE"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick]
You might want to log this to stderr.

Suggested change
echo "RUN MIGRATION is TRUE"
>&2 echo "RUN MIGRATION is TRUE"

#./manage.py createsuperuser

# start the server
./manage.py $@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have a misunderstanding here. I referred to the exec Bash built-in. How would it prevent running the command specified in CMD?

fi

# start the server
./manage.py $@

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just using $@ verbatim has unintended consequences! ⚠️ Compare these two:

bash -c 'python3 -c "import sys;print(sys.argv[2:])" -- $@' -- foo 'bar baz' --hello --world
# ['foo', 'bar', 'baz', '--hello', '--world']
bash -c 'python3 -c "import sys;print(sys.argv[2:])" -- "$@"' -- foo 'bar baz' --hello --world
# ['foo', 'bar baz', '--hello', '--world']

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants