Skip to content

Commit 62941c3

Browse files
authored
Merge pull request #16 from pacificclimate/maintenance-sprint-26q1
Maintenance sprint 26q1
2 parents 8281e00 + 5c8be03 commit 62941c3

4 files changed

Lines changed: 365 additions & 22 deletions

File tree

.github/workflows/docker-publish.yml

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,46 @@ on:
66
- '*'
77
tags:
88
- '[0-9]+.[0-9]+.[0-9]+'
9-
pull_request:
109

10+
permissions:
11+
contents: read
1112
jobs:
1213
publish:
1314

1415
runs-on: ubuntu-24.04
1516

1617
steps:
17-
- uses: actions/checkout@master
18-
- name: Publish to Registry
19-
uses: docker/build-push-action@v1
18+
- uses: actions/checkout@61b9e3751b92087fd0b06925ba6dd6314e06f089 # master
19+
with:
20+
persist-credentials: false
21+
- name: Log in to Docker Hub
22+
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
2023
with:
2124
username: ${{ secrets.pcicdevops_at_dockerhub_username }}
2225
password: ${{ secrets.pcicdevops_at_dockerhub_password }}
23-
repository: pcic/geospatial-python
24-
tag_with_ref: true
26+
27+
- name: Publish to Registry
28+
uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0
29+
with:
30+
push: true
31+
tags: |
32+
pcic/geospatial-python:${{ github.ref_name }}
33+
${{ github.ref_name == 'master' && 'pcic/geospatial-python:latest' || '' }}
34+
35+
smoke-test:
36+
needs: publish
37+
runs-on: ubuntu-24.04
38+
steps:
39+
- uses: actions/checkout@61b9e3751b92087fd0b06925ba6dd6314e06f089 # master
40+
with:
41+
persist-credentials: false
42+
43+
- name: Pull the published image
44+
run: docker pull pcic/geospatial-python:${{ github.ref_name }}
45+
46+
- name: Verify each library imports and reports a version
47+
run: |
48+
docker run --rm \
49+
-v "$PWD/ci:/ci:ro" \
50+
pcic/geospatial-python:${{ github.ref_name }} \
51+
python3 /ci/smoke_test.py

.gitignore

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[codz]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST
28+
29+
# PyInstaller
30+
# Usually these files are written by a python script from a template
31+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32+
*.manifest
33+
*.spec
34+
35+
# Installer logs
36+
pip-log.txt
37+
pip-delete-this-directory.txt
38+
39+
# Unit test / coverage reports
40+
htmlcov/
41+
.tox/
42+
.nox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
*.py.cover
50+
*.lcov
51+
.hypothesis/
52+
.pytest_cache/
53+
cover/
54+
55+
# Translations
56+
*.mo
57+
*.pot
58+
59+
# Django stuff:
60+
*.log
61+
local_settings.py
62+
db.sqlite3
63+
db.sqlite3-journal
64+
65+
# Flask stuff:
66+
instance/
67+
.webassets-cache
68+
69+
# Scrapy stuff:
70+
.scrapy
71+
72+
# Sphinx documentation
73+
docs/_build/
74+
75+
# PyBuilder
76+
.pybuilder/
77+
target/
78+
79+
# Jupyter Notebook
80+
.ipynb_checkpoints
81+
82+
# IPython
83+
profile_default/
84+
ipython_config.py
85+
86+
# pyenv
87+
# For a library or package, you might want to ignore these files since the code is
88+
# intended to run in multiple environments; otherwise, check them in:
89+
# .python-version
90+
91+
# pipenv
92+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
93+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
94+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
95+
# install all needed dependencies.
96+
# Pipfile.lock
97+
98+
# UV
99+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
100+
# This is especially recommended for binary packages to ensure reproducibility, and is more
101+
# commonly ignored for libraries.
102+
# uv.lock
103+
104+
# poetry
105+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106+
# This is especially recommended for binary packages to ensure reproducibility, and is more
107+
# commonly ignored for libraries.
108+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109+
# poetry.lock
110+
# poetry.toml
111+
112+
# pdm
113+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
115+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
116+
# pdm.lock
117+
# pdm.toml
118+
.pdm-python
119+
.pdm-build/
120+
121+
# pixi
122+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
123+
# pixi.lock
124+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
125+
# in the .venv directory. It is recommended not to include this directory in version control.
126+
.pixi/*
127+
!.pixi/config.toml
128+
129+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
130+
__pypackages__/
131+
132+
# Celery stuff
133+
celerybeat-schedule*
134+
celerybeat.pid
135+
136+
# Redis
137+
*.rdb
138+
*.aof
139+
*.pid
140+
141+
# RabbitMQ
142+
mnesia/
143+
rabbitmq/
144+
rabbitmq-data/
145+
146+
# ActiveMQ
147+
activemq-data/
148+
149+
# SageMath parsed files
150+
*.sage.py
151+
152+
# Environments
153+
.env
154+
.envrc
155+
.venv
156+
env/
157+
venv/
158+
ENV/
159+
env.bak/
160+
venv.bak/
161+
162+
# Spyder project settings
163+
.spyderproject
164+
.spyproject
165+
166+
# Rope project settings
167+
.ropeproject
168+
169+
# mkdocs documentation
170+
/site
171+
172+
# mypy
173+
.mypy_cache/
174+
.dmypy.json
175+
dmypy.json
176+
177+
# Pyre type checker
178+
.pyre/
179+
180+
# pytype static type analyzer
181+
.pytype/
182+
183+
# Cython debug symbols
184+
cython_debug/
185+
186+
# PyCharm
187+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
188+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
189+
# and can be added to the global gitignore or merged into this file. For a more nuclear
190+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
191+
# .idea/
192+
193+
# Abstra
194+
# Abstra is an AI-powered process automation framework.
195+
# Ignore directories containing user credentials, local state, and settings.
196+
# Learn more at https://abstra.io/docs
197+
.abstra/
198+
199+
# Visual Studio Code
200+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
201+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
202+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
203+
# you could uncomment the following to ignore the entire vscode folder
204+
# .vscode/
205+
# Temporary file for partial code execution
206+
tempCodeRunnerFile.py
207+
208+
# Ruff stuff:
209+
.ruff_cache/
210+
211+
# PyPI configuration file
212+
.pypirc
213+
214+
# Marimo
215+
marimo/_static/
216+
marimo/_lsp/
217+
__marimo__/
218+
219+
# Streamlit
220+
.streamlit/secrets.toml

Dockerfile

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,77 @@
1-
FROM ubuntu:24.04
1+
# syntax=docker/dockerfile:1
22

3-
LABEL Maintainer="James Hiebert <hiebert@uvic.ca>"
3+
# Ubuntu 26.04 LTS ships Python 3.14 and GDAL 3.12 as distro defaults, so the
4+
# GDAL Python bindings (built from source against libgdal-dev) match the system
5+
# library exactly. The build is split into two stages: a build stage with the
6+
# compilers and -dev headers needed to compile the C extensions, and a slim
7+
# runtime stage that carries only the shared libraries they link against.
8+
9+
############################
10+
# Build stage
11+
############################
12+
FROM ubuntu:26.04 AS build
13+
14+
LABEL org.opencontainers.image.authors="James Hiebert <hiebert@uvic.ca>"
415

516
ARG DEBIAN_FRONTEND=noninteractive
17+
ENV PIP_NO_CACHE_DIR=1 \
18+
PIP_DISABLE_PIP_VERSION_CHECK=1
19+
20+
RUN apt-get update && apt-get install -y --no-install-recommends \
21+
python3 \
22+
python3-dev \
23+
python3-venv \
24+
g++ \
25+
libgdal-dev \
26+
libhdf5-dev \
27+
libnetcdf-dev \
28+
libyaml-dev \
29+
libpq-dev \
30+
&& rm -rf /var/lib/apt/lists/*
31+
32+
# Build into an isolated virtualenv instead of the system interpreter; this
33+
# avoids pip's --break-system-packages
34+
RUN python3 -m venv /opt/venv
35+
ENV PATH="/opt/venv/bin:$PATH" \
36+
VIRTUAL_ENV="/opt/venv"
637

7-
RUN apt-get update && apt-get install -yq \
8-
libhdf5-dev \
9-
libnetcdf-dev \
10-
libyaml-dev \
11-
libgdal-dev \
12-
python3 \
13-
python3-dev \
14-
python3-pip \
15-
cython3 && \
16-
rm -rf /var/lib/apt/lists/*
38+
# numpy must be present before GDAL so the gdal_array bindings are built with
39+
# numpy support. The GDAL binding version is pinned to whatever libgdal-dev the
40+
# distro provides, so the two can never drift apart.
41+
RUN pip install numpy
42+
RUN pip install \
43+
"gdal==$(gdal-config --version)" \
44+
h5py \
45+
netCDF4 \
46+
psycopg2 \
47+
PyYAML \
48+
pillow
49+
50+
############################
51+
# Runtime stage
52+
############################
53+
FROM ubuntu:26.04 AS runtime
54+
55+
LABEL org.opencontainers.image.authors="James Hiebert <hiebert@uvic.ca>" \
56+
org.opencontainers.image.title="geospatial-python" \
57+
org.opencontainers.image.description="Ubuntu + Python base image for geospatial netCDF data and web apps" \
58+
org.opencontainers.image.source="https://github.com/pacificclimate/docker-geospatial-python"
59+
60+
ARG DEBIAN_FRONTEND=noninteractive
1761

18-
ENV CPLUS_INCLUDE_PATH=/usr/include/gdal
19-
ENV C_INCLUDE_PATH=/usr/include/gdal
62+
# Only the shared runtime libraries the compiled extensions link against
63+
# (libgdal38 pulls in PROJ, GEOS, etc. on its own). No compilers or headers.
64+
RUN apt-get update && apt-get install -y --no-install-recommends \
65+
python3 \
66+
libgdal38 \
67+
libhdf5-310 \
68+
libnetcdf22 \
69+
libpq5 \
70+
libyaml-0-2 \
71+
&& rm -rf /var/lib/apt/lists/*
2072

21-
RUN pip install numpy --break-system-packages
73+
COPY --from=build /opt/venv /opt/venv
2274

23-
RUN pip install gdal==3.8.4 h5py netCDF4 psycopg2 PyYAML pillow --break-system-packages
75+
ENV PATH="/opt/venv/bin:$PATH" \
76+
VIRTUAL_ENV="/opt/venv" \
77+
PYTHONUNBUFFERED=1

0 commit comments

Comments
 (0)