Skip to content

Commit 34deeec

Browse files
Fix rebuild?
1 parent 1ef9b11 commit 34deeec

2 files changed

Lines changed: 80 additions & 37 deletions

File tree

scripts/rebuild_frontend.sh

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,20 @@ web_container_id() {
163163
docker compose ps -q web 2>/dev/null | head -n 1
164164
}
165165

166+
compose_backend_is_podman() {
167+
if command -v podman-compose >/dev/null 2>&1; then
168+
return 0
169+
fi
170+
if docker compose version 2>/dev/null | grep -qi podman; then
171+
return 0
172+
fi
173+
return 1
174+
}
175+
166176
compose_cp_supported() {
177+
if compose_backend_is_podman; then
178+
return 1
179+
fi
167180
cd "${REPO_ROOT}"
168181
docker compose cp --help >/dev/null 2>&1
169182
}
@@ -231,31 +244,65 @@ count_files_in_proxy_container() {
231244
docker compose exec -T proxy sh -lc "find '${container_dir}' -type f 2>/dev/null | wc -l | tr -d ' '"
232245
}
233246

234-
reset_container_dir() {
235-
local cid="$1"
236-
local target_dir="$2"
237-
local reset_cmd="rm -rf '${target_dir}' && mkdir -p '${target_dir}'"
247+
reset_container_dir_via_compose() {
248+
local target_dir="$1"
249+
docker compose exec -T web bash -lc "rm -rf '${target_dir}' && mkdir -p '${target_dir}'"
250+
}
251+
252+
copy_host_tar_into_web() {
253+
local host_tar="$1"
254+
local container_tar="$2"
255+
local cid="$3"
256+
257+
cd "${REPO_ROOT}"
258+
if docker compose cp "${host_tar}" "web:${container_tar}" 2>/dev/null; then
259+
echo "rebuild_frontend.sh: staged deploy tar → web via compose cp" >&2
260+
return 0
261+
fi
262+
238263
if [[ -n "${cid}" ]] && podman_cli_available; then
239-
podman exec "${cid}" bash -lc "${reset_cmd}"
240-
else
241-
docker compose exec -T web bash -lc "${reset_cmd}"
264+
podman cp "${host_tar}" "${cid}:${container_tar}"
265+
echo "rebuild_frontend.sh: staged deploy tar → web via podman cp" >&2
266+
return 0
242267
fi
268+
269+
echo "rebuild_frontend.sh: failed to copy deploy tar into web container" >&2
270+
return 1
243271
}
244272

245-
copy_tree_via_compose_cp() {
273+
copy_tree_via_staged_tar() {
246274
local dest="$1"
247-
docker compose cp "${STATIC_FRONTEND}/." "web:${dest}/"
275+
local cid host_tar container_tar
276+
277+
cid="$(web_container_id)"
278+
if [[ -z "${cid}" ]]; then
279+
echo "rebuild_frontend.sh: web container id not found (is the web service running?)" >&2
280+
exit 1
281+
fi
282+
283+
host_tar="$(mktemp /tmp/hps-frontend-deploy.XXXXXX.tar)"
284+
container_tar="/tmp/hps-frontend-deploy.${$}.${RANDOM}.tar"
285+
286+
tar -C "${STATIC_FRONTEND}" -cf "${host_tar}" .
287+
if ! copy_host_tar_into_web "${host_tar}" "${container_tar}" "${cid}"; then
288+
rm -f "${host_tar}"
289+
exit 1
290+
fi
291+
rm -f "${host_tar}"
292+
293+
# Extract inside web via compose exec so writes land on the staticfiles_data volume.
294+
docker compose exec -T web bash -lc \
295+
"rm -rf '${dest}' && mkdir -p '${dest}' && tar -xf '${container_tar}' -C '${dest}' && rm -f '${container_tar}'"
248296
}
249297

250-
copy_tree_via_podman_exec_tar() {
251-
local cid="$1"
252-
local dest="$2"
253-
tar -C "${STATIC_FRONTEND}" -cf - . | podman exec -i "${cid}" tar -xf - -C "${dest}"
298+
copy_tree_via_compose_cp() {
299+
local dest="$1"
300+
reset_container_dir_via_compose "${dest}"
301+
docker compose cp "${STATIC_FRONTEND}/." "web:${dest}/"
254302
}
255303

256304
copy_tree_into_container() {
257-
local cid="$1"
258-
local dest="$2"
305+
local dest="$1"
259306

260307
if compose_cp_supported; then
261308
echo "rebuild_frontend.sh: copying via docker compose cp → ${dest}" >&2
@@ -264,34 +311,24 @@ copy_tree_into_container() {
264311
fi
265312

266313
if ! podman_cli_available; then
267-
echo "rebuild_frontend.sh: compose cp unavailable and podman not on PATH; cannot deploy into web" >&2
268-
exit 1
269-
fi
270-
271-
if [[ -z "${cid}" ]]; then
272-
echo "rebuild_frontend.sh: web container id not found (is the web service running?)" >&2
314+
echo "rebuild_frontend.sh: podman-compose detected but podman not on PATH; cannot deploy into web" >&2
273315
exit 1
274316
fi
275317

276-
# podman cp can write to the container layer instead of a bind-mounted volume on some
277-
# podman-compose setups; streaming tar through podman exec -i targets the mount reliably.
278-
echo "rebuild_frontend.sh: copying via podman exec -i tar → ${dest}" >&2
279-
reset_container_dir "${cid}" "${dest}"
280-
copy_tree_via_podman_exec_tar "${cid}" "${dest}"
318+
# podman-compose: stdin tar and direct tree cp are unreliable for named volumes; stage a
319+
# tar on /tmp in the container, then extract with compose exec onto the volume mount.
320+
echo "rebuild_frontend.sh: copying via staged tar + compose exec extract → ${dest}" >&2
321+
copy_tree_via_staged_tar "${dest}"
281322
}
282323

283324
copy_frontend_into_web() {
284325
cd "${REPO_ROOT}"
285-
local cid
286-
cid="$(web_container_id)"
287326

288327
# nginx (proxy) reads STATIC_ROOT/frontend from the shared staticfiles_data volume.
289-
reset_container_dir "${cid}" "${CONTAINER_STATIC_ROOT_FRONTEND}"
290-
copy_tree_into_container "${cid}" "${CONTAINER_STATIC_ROOT_FRONTEND}"
328+
copy_tree_into_container "${CONTAINER_STATIC_ROOT_FRONTEND}"
291329

292330
# Keep image source tree in sync for future collectstatic / container rebuilds.
293-
reset_container_dir "${cid}" "${CONTAINER_STATIC_FRONTEND}"
294-
copy_tree_into_container "${cid}" "${CONTAINER_STATIC_FRONTEND}"
331+
copy_tree_into_container "${CONTAINER_STATIC_FRONTEND}"
295332
}
296333

297334
sha256_in_web_container() {
@@ -405,6 +442,7 @@ deploy_to_compose() {
405442
verify_proxy_file_count_matches_web
406443
print_container_deploy_fingerprint "web STATIC_ROOT" web "${CONTAINER_STATIC_ROOT_FRONTEND}/machine/index.html"
407444
print_container_deploy_fingerprint "proxy nginx volume" proxy "${PROXY_STATIC_ROOT_FRONTEND}/machine/index.html"
445+
print_deploy_fingerprint "host build (expected)" "${STATIC_FRONTEND}/machine/index.html"
408446

409447
echo "Frontend deploy complete. Use the proxy service (ports 80/443), not web:8000 — Gunicorn does not serve /machine/."
410448
echo "Hard-refresh the browser and confirm the deploy fingerprint above matches page-*.js in DevTools Network."

scripts/test_rebuild_frontend_verify.sh

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,25 @@ cleanup() {
1515
}
1616
trap cleanup EXIT
1717

18-
for fn in copy_frontend_into_web compose_cp_supported web_container_id verify_container_frontend_matches_host verify_proxy_frontend_matches_web print_container_deploy_fingerprint; do
18+
for fn in copy_frontend_into_web compose_cp_supported web_container_id verify_container_frontend_matches_host verify_proxy_frontend_matches_web copy_tree_via_staged_tar compose_backend_is_podman; do
1919
if ! declare -F "${fn}" >/dev/null; then
2020
echo "expected ${fn} to be defined in rebuild_frontend.sh" >&2
2121
exit 1
2222
fi
2323
done
2424

25-
if ! grep -q 'copy_tree_via_podman_exec_tar' "${REBUILD_SCRIPT}"; then
26-
echo "expected podman exec -i tar deploy path in rebuild_frontend.sh" >&2
25+
if ! grep -q 'copy_tree_via_staged_tar' "${REBUILD_SCRIPT}"; then
26+
echo "expected staged tar deploy path in rebuild_frontend.sh" >&2
2727
exit 1
2828
fi
2929

30-
if ! grep -q 'podman exec -i tar →' "${REBUILD_SCRIPT}"; then
31-
echo "expected podman exec -i tar as primary podman deploy in rebuild_frontend.sh" >&2
30+
if ! grep -q 'staged tar + compose exec extract' "${REBUILD_SCRIPT}"; then
31+
echo "expected staged tar + compose exec extract message in rebuild_frontend.sh" >&2
32+
exit 1
33+
fi
34+
35+
if ! grep -q 'compose_backend_is_podman' "${REBUILD_SCRIPT}"; then
36+
echo "expected podman-compose detection in rebuild_frontend.sh" >&2
3237
exit 1
3338
fi
3439

0 commit comments

Comments
 (0)