diff --git a/CHANGELOG.md b/CHANGELOG.md index fa35f39..b848f3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ Notable changes to the Evomedia.net Token Savers. ## Unreleased ### Fixed +- **`zdeploy` edge kind now ships asset subdirectories** (#42) — the edge + deploy uploaded top-level files only, so a project self-hosting assets + in folders (`fonts/`, `vendor/`) lost them on every deploy: docker + created empty root-owned mount points and nginx served 404s from them, + which shows up as fonts silently falling back and vendored JS never + loading. Every subdirectory except `nginx-logs/` and `.git/` now ships + recursively, and the `ensure edge dir` chown is recursive so scp into + docker-created root-owned dirs cannot fail. - **`zdeploy` no longer deletes operator-managed files on deploy** (#2) — the project-directory replacement preserved only `./.env`, silently destroying every other server-side file (`.env.db`, staged signing diff --git a/CHECKSUMS.txt b/CHECKSUMS.txt index fb64473..726e9de 100644 --- a/CHECKSUMS.txt +++ b/CHECKSUMS.txt @@ -8,7 +8,7 @@ c336a61cb8563736bd6550671d7dc90b14702a43f25a97b1ac15ffd64605fbf6 zbackup_ec2.cm 20e6282901a919aa32ea717c739ba2dc9657426dff860f0e5fce201edefd99da zchecksums.cmd 692b7b0ff9e51e5d9b880358b33c54d2db4f967297a5350e154df1ce6f06ebc6 zchecksums.ps1 b56085112e7c573926a70a58872163b71416d58ce91ea7114b1f5de5fc96c982 zdeploy.cmd -c4189cef72368487af4524a00603967d7c8dc03c58ace5d4dd1e264ce1d22bd9 zdeploy.ps1 +c847a5b8e679014e1d363c23966fcaf95e443e10cde4f76f197b27a0aa8b9746 zdeploy.ps1 fa817d3bd7bba98b03b411d3c5a82b210d3cca316ac0c9785afa5b4ac5fe0766 zec2.cmd 5f70432af23df3459a98d9ad6a0da723783f2269dd5f5ab8ecdd6366ebc84942 zec2.ps1 4df94eda29b6f5b2cb6bfa63e0add4d90ea24d936305f36a69988e8dd5d69154 zec2_rotatekeys.cmd diff --git a/zdeploy.ps1 b/zdeploy.ps1 index ed135b6..5f863ec 100644 --- a/zdeploy.ps1 +++ b/zdeploy.ps1 @@ -620,10 +620,13 @@ function Invoke-EdgeDeploy { } Invoke-Ec2Step "ensure shared web network" "sudo docker network create web 2>/dev/null || true" - Invoke-Ec2Step "ensure edge dir" "sudo mkdir -p $remotePath && sudo chown ${Ec2User}:${Ec2User} $remotePath" + # -R: docker creates mount-point subdirs (vendor/, fonts/) root-owned when + # they are missing at compose up; a non-recursive chown leaves those + # unwritable and every scp into them fails. + Invoke-Ec2Step "ensure edge dir" "sudo mkdir -p $remotePath && sudo chown -R ${Ec2User}:${Ec2User} $remotePath" # Ship every top-level file in the edge folder — nginx.conf, compose, css, - # htpasswd, whatever the proxy serves. Subdirectories (logs, certs) stay put. + # htpasswd, whatever the proxy serves. $files = @(Get-ChildItem -LiteralPath $root -File | Where-Object { $_.Name -ne 'nul' }) foreach ($f in $files) { Write-Host " >> uploading $($f.Name)" -ForegroundColor DarkCyan @@ -631,6 +634,18 @@ function Invoke-EdgeDeploy { if ($LASTEXITCODE -ne 0) { throw "SCP failed for $($f.Name) (exit $LASTEXITCODE)" } } + # Content subdirectories the proxy serves (fonts/, vendor/, ...) ship too — + # only server-side state stays put. Skipping them is how self-hosted assets + # silently never reach prod: docker creates empty mount-point dirs and nginx + # serves 404s from them, so fonts fall back and vendored JS never loads. + $skipDirs = @('nginx-logs', '.git') + $dirs = @(Get-ChildItem -LiteralPath $root -Directory | Where-Object { $skipDirs -notcontains $_.Name }) + foreach ($d in $dirs) { + Write-Host " >> uploading $($d.Name)/ (recursive)" -ForegroundColor DarkCyan + scp -r -i $PEM_KEY $d.FullName "${SSH_TARGET}:$remotePath/" + if ($LASTEXITCODE -ne 0) { throw "SCP failed for $($d.Name) (exit $LASTEXITCODE)" } + } + $certMount = if ($Proj.certsSource) { "-v $($Proj.certsSource):/etc/letsencrypt/:ro " } else { "" } Invoke-Ec2Step "validate new nginx.conf" "sudo docker run --rm -v $remotePath/nginx.conf:/etc/nginx/nginx.conf:ro ${certMount}nginx:1.27-alpine nginx -t -c /etc/nginx/nginx.conf"