-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbuild-images.sh
More file actions
132 lines (115 loc) · 4.58 KB
/
build-images.sh
File metadata and controls
132 lines (115 loc) · 4.58 KB
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
#!/bin/bash
# Terminate on error
set -e
# Prepare variables for later use
images=()
# The image will be pushed to GitHub container registry
repobase="${REPOBASE:-ghcr.io/nethserver}"
# Configure the image name
reponame="webserver"
# PHP versions to build: "version" "base-image" (pairs)
declare -a PHP_VERSIONS=(
"8.5" "docker.io/library/php:8.5.4-fpm-bookworm"
"8.4" "docker.io/library/php:8.4.19-fpm-bookworm"
"8.3" "docker.io/library/php:8.3.30-fpm-bookworm"
"8.2" "docker.io/library/php:8.2.30-fpm-bookworm"
"8.1" "docker.io/library/php:8.1.34-fpm-bookworm"
"8.0" "docker.io/library/php:8.0.30-fpm-bullseye"
"7.4" "docker.io/library/php:7.4.33-fpm-bullseye"
)
# Secure temp dir for FIFO (avoids TOCTOU race of mktemp -u)
tmpdir=$(mktemp -d)
result_fifo="${tmpdir}/result.fifo"
mkfifo "${result_fifo}"
# Open FIFO read-write to avoid blocking on open (no writer needed yet)
exec 3<> "${result_fifo}"
declare -a pids=()
kill_all_builds() {
for pid in "${pids[@]}"; do
pkill -P "${pid}" 2>/dev/null || true # kill podman and other children first
kill "${pid}" 2>/dev/null || true # then kill the bash wrapper
done
}
trap 'kill_all_builds; exec 3<&-; exec 3>&-; rm -rf "${tmpdir}"' EXIT
trap 'kill_all_builds; exit 130' INT
trap 'kill_all_builds; exit 143' TERM
# Launch all PHP FPM builds in parallel
for (( i=0; i<${#PHP_VERSIONS[@]}; i+=2 )); do
version="${PHP_VERSIONS[$i]}"
php_image="${PHP_VERSIONS[$((i+1))]}"
echo "Starting build php${version}-fpm (${php_image})..."
(
result=0
# Reports result to FIFO on exit; handles normal exit and SIGTERM.
# SIGKILL would bypass this trap, but is an acceptable limitation for a build script.
trap 'printf "%s %d\n" "${version}" "${result}" > "${result_fifo}" 2>/dev/null || true' EXIT
set -o pipefail
podman build \
--force-rm \
--layers \
--cache-from "${repobase}/php${version}-fpm" \
--tag "${repobase}/php${version}-fpm" \
--build-arg "PHP_VERSION_IMAGE=${php_image}" \
container 2>&1 | sed -u "s/^/[php${version}] /" || result=$?
) &
pids+=("$!")
done
# Read results in completion order; stop everything on first failure
total=${#pids[@]}
for (( completed=0; completed<total; completed++ )); do
read -r done_version done_result <&3
if [[ "${done_result}" -ne 0 ]]; then
echo "[php${done_version}] BUILD FAILED - killing remaining builds..."
exit 1
fi
echo "[php${done_version}] BUILD OK"
done
# Reap all background build jobs to avoid zombies
wait "${pids[@]}"
for (( i=0; i<${#PHP_VERSIONS[@]}; i+=2 )); do
images+=("${repobase}/php${PHP_VERSIONS[$i]}-fpm")
done
# Create a new empty container image
container=$(buildah from scratch)
# Reuse existing nodebuilder-webserver container, to speed up builds
if ! buildah containers --format "{{.ContainerName}}" | grep -q nodebuilder-webserver; then
echo "Pulling NodeJS runtime..."
buildah from --name nodebuilder-webserver -v "${PWD}:/usr/src:Z" docker.io/library/node:24-slim
fi
echo "Build static UI files with node..."
buildah run --env="NODE_OPTIONS=--openssl-legacy-provider" nodebuilder-webserver sh -c "cd /usr/src/ui && yarn install && yarn build"
# Add imageroot directory to the container image
buildah add "${container}" imageroot /imageroot
buildah add "${container}" ui/dist /ui
# Setup the entrypoint, ask to reserve one TCP port with the label and set a rootless container
buildah config --entrypoint=/ \
--label="org.nethserver.authorizations=node:fwadm traefik@node:routeadm" \
--label="org.nethserver.tcp-ports-demand=2" \
--label="org.nethserver.rootfull=0" \
--label="org.nethserver.images=docker.io/nginx:1.28.0-alpine docker.io/drakkan/sftpgo:v2.7.1-alpine" \
"${container}"
# Commit the image
buildah commit "${container}" "${repobase}/${reponame}"
# Append the image URL to the images array
images+=("${repobase}/${reponame}")
#
# NOTICE:
#
# It is possible to build and publish multiple images.
#
# 1. create another buildah container
# 2. add things to it and commit it
# 3. append the image url to the images array
#
#
# Setup CI when pushing to Github.
# Warning! docker::// protocol expects lowercase letters (,,)
if [[ -n "${CI}" ]]; then
# Set output value for Github Actions
printf "::set-output name=images::%s\n" "${images[*],,}"
else
# Just print info for manual push
printf "Publish the images with:\n\n"
for image in "${images[@],,}"; do printf " buildah push %s docker://%s:%s\n" "${image}" "${image}" "${IMAGETAG:-latest}" ; done
printf "\n"
fi