Skip to content

Commit 0aa6a21

Browse files
authored
run Dockerfile from Python venv and update to Ubuntu Noble (#2107)
1 parent 26d4ce6 commit 0aa6a21

File tree

15 files changed

+117
-111
lines changed

15 files changed

+117
-111
lines changed

.github/workflows/containers.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ env:
1818
jobs:
1919
on-success:
2020
name: Build, Test and Push Docker Image to DockerHub
21-
runs-on: ubuntu-22.04
21+
runs-on: ubuntu-24.04
2222
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
2323
permissions:
2424
packages: write
@@ -80,7 +80,7 @@ jobs:
8080
platforms: linux/arm64, linux/amd64
8181

8282
on-failure:
83-
runs-on: ubuntu-22.04
83+
runs-on: ubuntu-24.04
8484
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
8585
steps:
8686
- name: Print Test Fail

.github/workflows/docs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ on:
1717

1818
jobs:
1919
main:
20-
runs-on: ubuntu-22.04
20+
runs-on: ubuntu-24.04
2121
strategy:
2222
matrix:
2323
include:
24-
- python-version: '3.10'
24+
- python-version: '3.12'
2525
steps:
2626
- uses: actions/checkout@master
2727
- uses: actions/setup-python@v5

.github/workflows/flake8.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ on:
55

66
jobs:
77
flake8_py3:
8-
runs-on: ubuntu-22.04
8+
runs-on: ubuntu-24.04
99
steps:
1010
- uses: actions/checkout@master
1111
- uses: actions/setup-python@v5
1212
name: setup Python
1313
with:
14-
python-version: '3.10'
14+
python-version: '3.12'
1515
- name: Checkout pygeoapi
1616
uses: actions/checkout@master
1717
- name: Install flake8

.github/workflows/main.yml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ on:
1717

1818
jobs:
1919
main:
20-
runs-on: ubuntu-22.04
20+
runs-on: ubuntu-24.04
2121
strategy:
2222
matrix:
2323
include:
24-
- python-version: '3.10'
24+
- python-version: '3.12'
2525
env:
2626
PYGEOAPI_CONFIG: "$(pwd)/pygeoapi-config.yml"
2727

@@ -103,26 +103,30 @@ jobs:
103103
packages: libsqlite3-mod-spatialite
104104
version: 4.3.0a-6build1
105105
- name: Use ubuntuGIS unstable ppa
106-
run: sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable && sudo apt update
106+
run: |
107+
sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
108+
sudo apt update
109+
sudo apt-get install gdal-bin libgdal-dev -y
107110
shell: bash
108-
- name: Install GDAL with Python bindings
109-
uses: awalsh128/[email protected]
110-
with:
111-
packages: gdal-bin libgdal-dev
112-
version: 3.8.4
111+
# - name: Install GDAL with Python bindings
112+
# uses: awalsh128/[email protected]
113+
# with:
114+
# packages: gdal-bin libgdal-dev
115+
# version: 3.11.3
113116
- name: Install and run Oracle
114117
run: |
115118
docker run -d --name oracledb -e ORACLE_PWD=oracle -v ${{ github.workspace }}/tests/data/oracle/init-db:/opt/oracle/scripts/startup -p 1521:1521 container-registry.oracle.com/database/express:21.3.0-xe
116119
- name: Install requirements 📦
117120
run: |
121+
pip3 install setuptools
118122
pip3 install -r requirements.txt
119123
pip3 install -r requirements-admin.txt
120124
pip3 install -r requirements-starlette.txt
121125
pip3 install -r requirements-dev.txt
122126
pip3 install -r requirements-provider.txt
123127
pip3 install -r requirements-manager.txt
124128
pip3 install -r requirements-django.txt
125-
python3 setup.py install
129+
pip3 install .
126130
pip3 install --global-option=build_ext --global-option="-I/usr/include/gdal" GDAL==`gdal-config --version`
127131
- name: setup test data ⚙️
128132
run: |

.github/workflows/vulnerabilities.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ on:
1616
jobs:
1717

1818
vulnerabilities:
19-
runs-on: ubuntu-22.04
19+
runs-on: ubuntu-24.04
2020
defaults:
2121
run:
2222
working-directory: .

.readthedocs.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ sphinx:
77
configuration: docs/source/conf.py
88

99
build:
10-
os: ubuntu-22.04
10+
os: ubuntu-24.04
1111
tools:
12-
python: "3.11"
12+
python: "3.12"
1313

1414
python:
1515
install:

Dockerfile

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Francesco Bartoli <[email protected]>
66
# Angelos Tzotsos <[email protected]>
77
#
8-
# Copyright (c) 2020 Tom Kralidis
8+
# Copyright (c) 2025 Tom Kralidis
99
# Copyright (c) 2019 Just van den Broecke
1010
# Copyright (c) 2025 Francesco Bartoli
1111
# Copyright (c) 2025 Angelos Tzotsos
@@ -34,7 +34,7 @@
3434
#
3535
# =================================================================
3636

37-
FROM ubuntu:jammy-20250714
37+
FROM ubuntu:noble-20250805
3838

3939
LABEL maintainer="Just van den Broecke <[email protected]>"
4040

@@ -93,20 +93,20 @@ ENV TZ=${TZ} \
9393
DEB_PACKAGES="\
9494
locales \
9595
tzdata \
96-
gunicorn \
9796
python3-dateutil \
9897
python3-gevent \
9998
python3-greenlet \
10099
python3-pip \
101100
python3-tz \
101+
python3-venv \
102102
python3-yaml \
103-
${ADD_DEB_PACKAGES}"
103+
${ADD_DEB_PACKAGES}" \
104+
PROJ_LIB=/usr/share/proj
104105

105106
WORKDIR /pygeoapi
106107

107108
# Install operating system dependencies
108-
RUN \
109-
apt-get update -y \
109+
RUN apt-get update -y \
110110
&& apt-get install -y ${DEB_BUILD_DEPS} \
111111
&& add-apt-repository ppa:ubuntugis/ubuntugis-unstable \
112112
&& apt-get --no-install-recommends install -y ${DEB_PACKAGES} \
@@ -126,24 +126,21 @@ RUN \
126126
&& apt autoremove -y \
127127
&& rm -rf /var/lib/apt/lists/*
128128

129-
ADD requirements-docker.txt requirements-admin.txt /pygeoapi/
130-
# Install remaining pygeoapi deps
131-
RUN python3 -m pip install --no-cache-dir -r requirements-docker.txt \
132-
&& python3 -m pip install --no-cache-dir -r requirements-admin.txt
133-
134-
135129
ADD . /pygeoapi
136130

137-
# Install pygeoapi
138-
RUN python3 -m pip install --no-cache-dir -e .
131+
# Install remaining pygeoapi deps and pygeoapi itself
132+
RUN python3 -m venv --system-site-packages /venv \
133+
&& /venv/bin/python3 -m pip install --no-cache-dir -r requirements-docker.txt \
134+
&& /venv/bin/python3 -m pip install --no-cache-dir -r requirements-admin.txt \
135+
&& /venv/bin/python3 -m pip install --no-cache-dir gunicorn \
136+
&& /venv/bin/python3 -m pip install --no-cache-dir -e .
139137

140-
RUN \
141-
# Set default config and entrypoint for Docker Image
142-
cp /pygeoapi/docker/default.config.yml /pygeoapi/local.config.yml \
138+
# Set default config and entrypoint for Docker Image
139+
# and compile language files
140+
RUN cp /pygeoapi/docker/default.config.yml /pygeoapi/local.config.yml \
143141
&& cp /pygeoapi/docker/entrypoint.sh /entrypoint.sh \
144-
# compile language files
145142
&& cd /pygeoapi \
146-
&& for i in locale/*; do echo $i && pybabel compile -d locale -l `basename $i`; done
147-
143+
&& for i in locale/*; do if [ "$i" != "locale/README.md" ]; then echo $i && pybabel compile -d locale -l `basename $i`; fi; done \
144+
&& chmod -R g=u /pygeoapi
148145

149146
ENTRYPOINT ["/entrypoint.sh"]

docker/entrypoint.sh

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
#
44
# Authors: Just van den Broecke <[email protected]>
55
# Benjamin Webb <[email protected]>
6+
# Tom Kralidis <[email protected]>
67
#
78
# Copyright (c) 2019 Just van den Broecke
89
# Copyright (c) 2024 Benjamin Webb
10+
# Copyright (c) 2025 Tom Kralidis
911
#
1012
# Permission is hereby granted, free of charge, to any person
1113
# obtaining a copy of this software and associated documentation
@@ -39,10 +41,10 @@ set +e
3941
export PYGEOAPI_HOME=/pygeoapi
4042

4143
if [[ -z "$PYGEOAPI_CONFIG" ]]; then
42-
export PYGEOAPI_CONFIG="${PYGEOAPI_HOME}/local.config.yml"
44+
export PYGEOAPI_CONFIG="${PYGEOAPI_HOME}/local.config.yml"
4345
fi
4446
if [[ -z "$PYGEOAPI_OPENAPI" ]]; then
45-
export PYGEOAPI_OPENAPI="${PYGEOAPI_HOME}/local.openapi.yml"
47+
export PYGEOAPI_OPENAPI="${PYGEOAPI_HOME}/local.openapi.yml"
4648
fi
4749

4850
# gunicorn env settings with defaults
@@ -60,8 +62,8 @@ entry_cmd=${1:-run}
6062

6163
# Shorthand
6264
function error() {
63-
echo "ERROR: $@"
64-
exit -1
65+
echo "ERROR: $@"
66+
exit -1
6567
}
6668

6769
# Workdir
@@ -70,71 +72,71 @@ cd ${PYGEOAPI_HOME}
7072
echo "Default config in ${PYGEOAPI_CONFIG}"
7173

7274
echo "Trying to generate openapi.yml"
73-
pygeoapi openapi generate ${PYGEOAPI_CONFIG} --output-file ${PYGEOAPI_OPENAPI}
75+
/venv/bin/pygeoapi openapi generate ${PYGEOAPI_CONFIG} --output-file ${PYGEOAPI_OPENAPI}
7476

7577
[[ $? -ne 0 ]] && error "openapi.yml could not be generated ERROR"
7678

7779
echo "openapi.yml generated continue to pygeoapi"
7880

7981
start_gunicorn() {
80-
# SCRIPT_NAME should not have value '/'
81-
[[ "${SCRIPT_NAME}" = '/' ]] && export SCRIPT_NAME="" && echo "make SCRIPT_NAME empty from /"
82-
83-
echo "Starting gunicorn name=${CONTAINER_NAME} on ${CONTAINER_HOST}:${CONTAINER_PORT} with ${WSGI_WORKERS} workers and SCRIPT_NAME=${SCRIPT_NAME}"
84-
exec gunicorn --workers ${WSGI_WORKERS} \
85-
--worker-class=${WSGI_WORKER_CLASS} \
86-
--timeout ${WSGI_WORKER_TIMEOUT} \
87-
--name=${CONTAINER_NAME} \
88-
--bind ${CONTAINER_HOST}:${CONTAINER_PORT} \
89-
${@} \
90-
${WSGI_APP}
82+
# SCRIPT_NAME should not have value '/'
83+
[[ "${SCRIPT_NAME}" = '/' ]] && export SCRIPT_NAME="" && echo "make SCRIPT_NAME empty from /"
84+
85+
echo "Starting gunicorn name=${CONTAINER_NAME} on ${CONTAINER_HOST}:${CONTAINER_PORT} with ${WSGI_WORKERS} workers and SCRIPT_NAME=${SCRIPT_NAME}"
86+
exec /venv/bin/gunicorn --workers ${WSGI_WORKERS} \
87+
--worker-class=${WSGI_WORKER_CLASS} \
88+
--timeout ${WSGI_WORKER_TIMEOUT} \
89+
--name=${CONTAINER_NAME} \
90+
--bind ${CONTAINER_HOST}:${CONTAINER_PORT} \
91+
${@} \
92+
${WSGI_APP}
9193
}
9294

9395
case ${entry_cmd} in
94-
# Run Unit tests
95-
test)
96-
for test_py in $(ls tests/test_*.py)
97-
do
98-
# Skip tests requiring backend server or libs installed
99-
case ${test_py} in
100-
tests/test_elasticsearch__provider.py)
101-
;&
102-
tests/test_sensorthings_provider.py)
103-
;&
104-
tests/test_postgresql_provider.py)
105-
;&
106-
tests/test_mongo_provider.py)
107-
echo "Skipping: ${test_py}"
108-
;;
109-
*)
110-
python3 -m pytest ${test_py}
111-
;;
112-
esac
113-
done
114-
;;
115-
116-
# Run pygeoapi server
117-
run)
118-
# Start
119-
start_gunicorn
120-
;;
121-
122-
# Run pygeoapi server with hot reload
123-
run-with-hot-reload)
124-
# Lock all Python files (for gunicorn hot reload), if running with user root
125-
if [[ $(id -u) -eq 0 ]]
126-
then
127-
echo "Running pygeoapi as root"
128-
find . -type f -name "*.py" | xargs chmod 0444
129-
fi
130-
131-
# Start with hot reload options
132-
start_gunicorn --reload --reload-extra-file ${PYGEOAPI_CONFIG}
133-
;;
134-
135-
*)
136-
error "unknown command arg: must be run (default), run-with-hot-reload, or test"
137-
;;
96+
# Run Unit tests
97+
test)
98+
for test_py in $(ls tests/test_*.py)
99+
do
100+
# Skip tests requiring backend server or libs installed
101+
case ${test_py} in
102+
tests/test_elasticsearch__provider.py)
103+
;&
104+
tests/test_sensorthings_provider.py)
105+
;&
106+
tests/test_postgresql_provider.py)
107+
;&
108+
tests/test_mongo_provider.py)
109+
echo "Skipping: ${test_py}"
110+
;;
111+
*)
112+
/venv/bin/python3 -m pytest ${test_py}
113+
;;
114+
esac
115+
done
116+
;;
117+
118+
# Run pygeoapi server
119+
run)
120+
# Start
121+
start_gunicorn
122+
;;
123+
124+
# Run pygeoapi server with hot reload
125+
run-with-hot-reload)
126+
# Lock all Python files (for gunicorn hot reload), if running with user root
127+
if [[ $(id -u) -eq 0 ]]
128+
then
129+
echo "Running pygeoapi as root"
130+
find . -type f -name "*.py" | xargs chmod 0444
131+
fi
132+
133+
# Start with hot reload options
134+
start_gunicorn --reload --reload-extra-file ${PYGEOAPI_CONFIG}
135+
;;
136+
137+
*)
138+
error "unknown command arg: must be run (default), run-with-hot-reload, or test"
139+
;;
138140
esac
139141

140142
echo "END /entrypoint.sh"

docs/source/development.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ Install Python with the option to enable SQLite extensions:
134134

135135
.. code-block:: bash
136136
137-
LDFLAGS="-L/usr/local/opt/sqlite/lib -L/usr/local/opt/zlib/lib" CPPFLAGS="-I/usr/local/opt/sqlite/include -I/usr/local/opt/zlib/include" PYTHON_CONFIGURE_OPTS="--enable-loadable-sqlite-extensions" pyenv install 3.10.12
137+
LDFLAGS="-L/usr/local/opt/sqlite/lib -L/usr/local/opt/zlib/lib" CPPFLAGS="-I/usr/local/opt/sqlite/include -I/usr/local/opt/zlib/include" PYTHON_CONFIGURE_OPTS="--enable-loadable-sqlite-extensions" pyenv install 3.12.3
138138
139139
Configure SQLite from Homebrew over that one shipped with the OS:
140140

docs/source/installation.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pygeoapi runs on Python 3.
1414
.. note::
1515

1616
The exact Python version requirements are aligned with the version of Python on the pygeoapi supported Ubuntu
17-
operating system version. For example, as of 2024-07, the supported version of Python is bound to Ubuntu 22.04
18-
(Jammy) which supports Python 3.10. Ensure you have a Python version that is compatible with the current Ubuntu
17+
operating system version. For example, as of 2024-07, the supported version of Python is bound to Ubuntu 24.04
18+
(Noble) which supports Python 3.12. Ensure you have a Python version that is compatible with the current Ubuntu
1919
version that is specified in pygeoapi's `Dockerfile`_.
2020

2121
Core dependencies are included as part of a given pygeoapi installation procedure. More specific requirements
@@ -34,7 +34,7 @@ For developers and the truly impatient
3434
cd pygeoapi
3535
pip3 install --upgrade pip
3636
pip3 install -r requirements.txt
37-
python3 setup.py install
37+
pip3 install .
3838
cp pygeoapi-config.yml example-config.yml
3939
vi example-config.yml # edit as required
4040
export PYGEOAPI_CONFIG=example-config.yml

0 commit comments

Comments
 (0)