-
Notifications
You must be signed in to change notification settings - Fork 0
/
blueprint_gdal.Dockerfile
441 lines (384 loc) · 13.8 KB
/
blueprint_gdal.Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# CentOS 7 with GDAL 3+
# - includes OPENJPEG 2.4, ECW J2K 5.5, libtiff4.3, libgeotiff 1.7, PROJ v8
# - compatible with pypi GDAL bindings (recipe does not build python bindings)
# - recipe is not currently compatible with GDAL 2.
#
# This dockerfile follows procedures from the offical GDAL dockers
# https://github.com/OSGeo/gdal/tree/master/gdal/docker
#
# This dockerfile is derived from the manylinux2014 base image, derived from
# CentOS 7 and already containing many updated build essentials.
# https://github.com/pypa/manylinux
#
# In the future, the manylinux2014 image could enable a portable GDAL that
# includes internal copies of necessary dependencies and python bindings
# for a selected python version. This recipe currently does not build any
# python bindings.
#
# As this base image includes build essentials already in /usr/local,
# libraries are staged in "/gdal/usr/local". The last build step clears
# /usr/local of other packages, then migrates the staging directory to
# /usr/local for consistency with other recipes.
# -----------------------------------------------------------------------------
# BASE IMAGE
# -----------------------------------------------------------------------------
# global args
ARG BASE_IMAGE="quay.io/pypa/manylinux2014_x86_64:2024-07-02-9ac04ee"
# base image
FROM ${BASE_IMAGE} AS base
# Set shell to bash
SHELL ["/usr/bin/env", "/bin/bash", "-euxvc"]
# staging & reporting directories, reused by each stage
ENV STAGING_DIR="/staging"
ENV REPORT_DIR="${STAGING_DIR}/usr/local/share/just/info"
RUN mkdir -p "${STAGING_DIR}" "${REPORT_DIR}";
# working directory (for download, unpack, build, etc.)
WORKDIR /tmp
# -----------------------------------------------------------------------------
# OPENJPEG v2
# -----------------------------------------------------------------------------
FROM base AS openjpeg
# version argument
ARG OPENJPEG_VERSION=2.4.0
# install
RUN \
# download & unzip
TAR_FILE="v${OPENJPEG_VERSION}.tar.gz"; \
curl -fsSLO "https://github.com/uclouvain/openjpeg/archive/${TAR_FILE}"; \
tar -xvf "${TAR_FILE}" --strip-components=1; \
#
# configure, build, & install
cmake . \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release; \
make -j"$(nproc)"; \
make install DESTDIR="${STAGING_DIR}"; \
echo "${OPENJPEG_VERSION}" > "${REPORT_DIR}/openjpeg_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# ECW v5
# -----------------------------------------------------------------------------
# By default (empty ECW_VERSION) this plugin will not be installed as the
# as the public download link is no longer available.
#
# Version options:
# ARG ECW_VERSION= # do not install installed
# ARG ECW_VERSION=5.4.0 # not currently available
# ARG ECW_VERSION=5.5.0 # not currently available
#
FROM base AS ecw
# version argument (do not install by default)
ARG ECW_VERSION=
# install
RUN \
# local variables
if [ -z "${ECW_VERSION:-}" ]; then \
echo "ECW decoder will not be installed"; \
exit 0; \
elif [ "${ECW_VERSION}" == "5.4.0" ]; then \
ZIP_FILE="erdas-ecw-sdk-5.4.0-update1-linux.zip"; \
ZIP_URL="https://downloads.hexagongeospatial.com/software/2018/ECW/${ZIP_FILE}"; \
UNPACK_DIR=/hexagon/ERDAS-ECW_JPEG_2000_SDK-5.4.0/Desktop_Read-Only; \
elif [ "${ECW_VERSION}" == "5.5.0" ]; then \
ZIP_FILE="erdas-ecw-jp2-sdk-v55-update-4-linux"; \
ZIP_URL="https://go2.hexagongeospatial.com/${ZIP_FILE}"; \
UNPACK_DIR=/root/hexagon/ERDAS-ECW_JPEG_2000_SDK-5.5.0/Desktop_Read-Only; \
else \
echo "Unrecognized ECW version ${ECW_VERSION}"; \
exit 1; \
fi; \
#
# download & unzip
curl -fsSLO "${ZIP_URL}"; \
unzip "${ZIP_FILE}"; \
#
# unpack & cleanup
printf '1\nyes\n' | MORE=-V bash ./*.bin; \
#
# copy necessary files
# this removes the "new ABI" .so files as they are note needed
LOCAL_DIR="${STAGING_DIR}/usr/local/ecw"; \
mkdir -p "${LOCAL_DIR}"; \
cp -r "${UNPACK_DIR}"/{*.txt,bin,etc,include,lib,third*} "${LOCAL_DIR}"; \
echo "${ECW_VERSION}" > "${REPORT_DIR}/ecw_version"; \
#
# remove the "new C++11 ABI"
rm -rf "${LOCAL_DIR}"/{lib/cpp11abi,lib/newabi} \
"${LOCAL_DIR}"/{lib/x64/debug,bin/x64/debug}; \
#
# cleanup
rm -rf "${UNPACK_DIR}" /tmp/*;
# link .so files to "/usr/local/lib" for easier discovery
RUN \
# skip linking if not installed
if [ -z "${ECW_VERSION:-}" ]; then \
echo "ECW decoder will not be installed"; \
exit 0; \
fi; \
# make links
mkdir -p "${STAGING_DIR}/usr/local/lib"; \
cd "${STAGING_DIR}/usr/local/lib"; \
ln -s ../ecw/lib/x64/release/libNCSEcw.so* .;
# -----------------------------------------------------------------------------
# GEOS
# -----------------------------------------------------------------------------
# https://libgeos.org
FROM base AS geos
# version argument
ARG GEOS_VERSION=3.11.0
# install
RUN \
# download & unzip
TAR_FILE="geos-${GEOS_VERSION}.tar.bz2"; \
curl -fsSLO "https://download.osgeo.org/geos/${TAR_FILE}"; \
tar -xf "${TAR_FILE}" --strip-components=1; \
#
# configure, build, & install
mkdir build; cd build; \
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="${STAGING_DIR}/usr/local" \
-DBUILD_DOCUMENTATION=OFF \
| tee "${REPORT_DIR}/geos_configure"; \
cmake --build . -j$(nproc); \
cmake --install .; \
echo "${GEOS_VERSION}" > "${REPORT_DIR}/geos_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# LIBTIFF
# -----------------------------------------------------------------------------
# https://gitlab.com/libtiff/libtiff
FROM base AS tiff
# version argument
ARG TIFF_VERSION=4.3.0
# additional build dependencies
RUN ulimit -n 1024; \
yum install -y \
libjpeg-turbo-devel \
zlib-devel; \
yum clean all
# install
RUN \
# download & unzip
TAR_FILE="tiff-${TIFF_VERSION}.tar.gz"; \
curl -fsSLO "https://download.osgeo.org/libtiff/${TAR_FILE}"; \
tar -xf "${TAR_FILE}" --strip-components=1; \
#
# configure, build, & install
./configure \
--disable-static \
| tee "${REPORT_DIR}/tiff_configure"; \
make -j"$(nproc)"; \
make install DESTDIR="${STAGING_DIR}"; \
echo "$TIFF_VERSION" > "${REPORT_DIR}/tiff_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# PROJ v6
# -----------------------------------------------------------------------------
# install instructions: https://proj.org/install.html
FROM base AS proj
# version argument
ARG PROJ_VERSION=8.1.1
# additional build dependencies
RUN ulimit -n 1024; \
yum install -y \
libcurl-devel \
libjpeg-turbo-devel \
zlib-devel; \
yum clean all
# local dependencies to staging directory
COPY --from=tiff ${STAGING_DIR}/usr/local /usr/local
# install
RUN \
# download & unzip
TAR_FILE="proj-${PROJ_VERSION}.tar.gz"; \
curl -fsSLO "https://download.osgeo.org/proj/${TAR_FILE}"; \
tar -xf ${TAR_FILE} --strip-components=1; \
#
# configure, build, & install
mkdir build; cd build; \
cmake .. \
-DCMAKE_INSTALL_PREFIX="${STAGING_DIR}/usr/local" \
-DCMAKE_INSTALL_LIBDIR="lib" \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_IPO=ON \
-DBUILD_TESTING:BOOL=OFF \
| tee "${REPORT_DIR}/proj_configure"; \
cmake --build . -j$(nproc); \
cmake --install .; \
echo "${PROJ_VERSION}" > "${REPORT_DIR}/proj_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# GEOTIFF
# -----------------------------------------------------------------------------
# https://github.com/OSGeo/libgeotiff
FROM base AS geotiff
# version argument
ARG GEOTIFF_VERSION=1.7.0
# additional build dependencies
RUN ulimit -n 1024; \
yum install -y \
libcurl-devel \
libjpeg-turbo-devel \
zlib-devel; \
yum clean all
# local dependencies to staging directory
COPY --from=tiff ${STAGING_DIR}/usr/local /usr/local
COPY --from=proj ${STAGING_DIR}/usr/local /usr/local
# install
RUN \
# download & unzip
TAR_FILE="libgeotiff-${GEOTIFF_VERSION}.tar.gz"; \
curl -fsSLO "https://download.osgeo.org/geotiff/libgeotiff/${TAR_FILE}"; \
tar -xf "${TAR_FILE}" --strip-components=1; \
#
# configure, build, & install
./configure \
--with-jpeg \
--with-proj=/usr/local \
--with-zlib \
| tee "${REPORT_DIR}/geotiff_configure"; \
make -j"$(nproc)"; \
make install DESTDIR="${STAGING_DIR}"; \
echo "$GEOTIFF_VERSION" > "${REPORT_DIR}/geotiff_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# GDAL setup for build
# -----------------------------------------------------------------------------
FROM base AS setup
# version argument
ARG GDAL_VERSION=3.3.3
ENV GDAL_VERSION=$GDAL_VERSION
# additional build dependencies
RUN ulimit -n 1024; \
yum install -y \
libcurl-devel \
libjpeg-turbo-devel \
zlib-devel; \
yum clean all
# download & unzip
RUN TAR_FILE="gdal-${GDAL_VERSION}.tar.gz"; \
curl -fsSLO "https://download.osgeo.org/gdal/${GDAL_VERSION}/${TAR_FILE}"; \
tar -xf "${TAR_FILE}" --strip-components=1; \
rm "${TAR_FILE}"
# -----------------------------------------------------------------------------
# GDAL build library
# -----------------------------------------------------------------------------
FROM setup AS library
# local dependencies to staging directory
# base manylinux image has many other dependencies already in /usr/local,
# so we isolate packages in the staging directory
COPY --from=openjpeg ${STAGING_DIR} ${STAGING_DIR}
COPY --from=ecw ${STAGING_DIR} ${STAGING_DIR}
COPY --from=geos ${STAGING_DIR} ${STAGING_DIR}
COPY --from=tiff ${STAGING_DIR} ${STAGING_DIR}
COPY --from=proj ${STAGING_DIR} ${STAGING_DIR}
COPY --from=geotiff ${STAGING_DIR} ${STAGING_DIR}
# local dependencies to /usr/local
# This is necessary only for those dependencies expected to be in a "normal"
# location. GDAL "configure" accepts direct paths for many packages, including
# ECW and PROJ.
COPY --from=openjpeg ${STAGING_DIR}/usr/local /usr/local
COPY --from=geos ${STAGING_DIR}/usr/local /usr/local
# add staged libraries
ENV LD_LIBRARY_PATH="${STAGING_DIR}/usr/local/lib"
# configure, build, & install
# https://raw.githubusercontent.com/OSGeo/gdal/master/gdal/configure
RUN \
# versions from file
function get_version() { cat "${REPORT_DIR}/${1}_version" 2>/dev/null || echo ""; }; \
ECW_VERSION=$(get_version ecw); \
# configure
./configure \
--without-libtool \
--with-hide-internal-symbols \
--with-jpeg=internal \
--with-png=internal \
--with-pcre=no \
--with-libtiff="${STAGING_DIR}/usr/local" \
--with-geotiff="${STAGING_DIR}/usr/local" \
--with-openjpeg \
--with-proj="${STAGING_DIR}/usr/local" \
${ECW_VERSION:+--with-ecw="${STAGING_DIR}/usr/local/ecw"} \
| tee "${REPORT_DIR}/gdal_configure"; \
#
# build & install
make -j "$(nproc)"; \
make install "DESTDIR=${STAGING_DIR}"; \
echo "${GDAL_VERSION}" > "${REPORT_DIR}/gdal_version"; \
#
# cleanup
rm -rf /tmp/*;
# -----------------------------------------------------------------------------
# GDAL build wheel
# -----------------------------------------------------------------------------
FROM setup AS wheel
# version argument
ARG PYTHON_VERSION=3.9
ARG NUMPY_VERSION=1.22.3
ARG PYPROJ_VERSION=3.3.0
# wheel directory
ENV WHEEL_DIR="${STAGING_DIR}/usr/local/share/just/wheels"
# local dependencies to /usr/local
COPY --from=library ${STAGING_DIR}/usr/local /usr/local
# build wheels
RUN mkdir -p "${WHEEL_DIR}"; \
# SWIG directory
SWIG_DIR="$(find . -type d -name 'swig' | head -n 1)"; \
#
# test for "use_2to3" in setup.py which requires older setuptools
# https://github.com/OSGeo/gdal/issues/4467#issuecomment-916676916
if grep -q 'use_2to3' "${SWIG_DIR}/python/setup.py"; then \
SETUPTOOLS_DEP="setuptools<58"; \
fi; \
#
# python flavor
PYBIN=$(ver=$(echo ${PYTHON_VERSION} | sed -E 's|(.)\.([^.]*).*|\1\2|'); \
echo /opt/python/cp${ver}-*/bin); \
#
# install python dependencies
# Note pyproj incompatibility with cython 3+
# https://github.com/pyproj4/pyproj/issues/1321
"${PYBIN}/pip" install \
${SETUPTOOLS_DEP:-} \
"cython<3" \
numpy==${NUMPY_VERSION}; \
#
# build gdal wheel
"${PYBIN}/pip" wheel "${SWIG_DIR}/python" \
--no-deps --no-build-isolation -w "${WHEEL_DIR}"; \
#
# build pyproj wheel
# While this project already provides manylinux wheels on pypi, building
# pyproj here ensures the wheel uses the installed libproj & PROJ_VERSION
"${PYBIN}/pip" wheel pyproj==${PYPROJ_VERSION} --no-binary pyproj \
--no-deps --no-build-isolation -w "${WHEEL_DIR}"; \
#
# cleanup
rm -rf /tmp/*; \
ls -la "${WHEEL_DIR}";
# -----------------------------------------------------------------------------
# GDAL final
# -----------------------------------------------------------------------------
FROM base
# clear /usr/local of all other packages
RUN rm -rf /usr/local/*
# migrate staging directory to /usr/local
COPY --from=library ${STAGING_DIR}/usr/local /usr/local
COPY --from=wheel ${STAGING_DIR}/usr/local /usr/local
# Patch file for downstream image
ENV GDAL_PATCH_FILE=/usr/local/share/just/container_build_patch/30_gdal
ADD 30_gdal ${GDAL_PATCH_FILE}
RUN chmod +x ${GDAL_PATCH_FILE}