ops(docker): prune unused cache on deploys and nightly
Add scripts/docker-prune.sh (build cache >72h capped at 4g, unreferenced images >7d, stopped containers >24h; never volumes), run it after every CI deploy and compose update, and schedule a nightly prune from the host-side jobs-worker. Tighten the deployment contract tests to assert the scoped-prune boundaries.
This commit is contained in:
1 parent
fb68df3ba9
commit
47917bb63b
6 files changed
+102
-5
No files matched your search
@@ -26,10 +26,18 @@ it("preserves production runtime configuration and recent cache", () => {
|
||||
expect(deploy).toContain("/var/www/Gamedata:/var/www/Gamedata");
|
||||
expect(deploy).toContain("/app/storage");
|
||||
expect(deploy).not.toContain("--env-file");
|
||||
expect(deploy).toContain(
|
||||
// The scoped prune lives in docker-prune.sh; deploys invoke it for both CI
|
||||
// and scheduled updates. It reclaims build cache + old unreferenced images
|
||||
// but never touches volumes.
|
||||
expect(deploy).toContain("bash \"$deploy_dir/scripts/docker-prune.sh\"");
|
||||
const prune = readFileSync("scripts/docker-prune.sh", "utf8");
|
||||
expect(prune).toContain(
|
||||
'docker builder prune -af --filter "until=72h" --max-used-space=4g',
|
||||
);
|
||||
expect(prune).toContain('docker image prune -af --filter "until=168h"');
|
||||
expect(prune).toContain('docker container prune -f --filter "until=24h"');
|
||||
expect(deploy).not.toContain("docker volume prune");
|
||||
expect(prune).not.toContain("docker volume prune");
|
||||
});
|
||||
it("builds the checked out source without fetching a moving remote branch", () => {
|
||||
const dockerfile = readFileSync("Dockerfile", "utf8");
|
||||
|
||||
@@ -46,6 +46,10 @@ function simulate(scenario: string) {
|
||||
resolve(root, "scripts/docker-update.sh"),
|
||||
join(dir, "scripts/docker-update.sh"),
|
||||
);
|
||||
copyFileSync(
|
||||
resolve(root, "scripts/docker-prune.sh"),
|
||||
join(dir, "scripts/docker-prune.sh"),
|
||||
);
|
||||
writeFileSync(join(dir, ".env"), "HOTEL_NAME=Test\n");
|
||||
if (scenario.startsWith("saved-"))
|
||||
writeFileSync(
|
||||
@@ -93,7 +97,7 @@ describe("Docker clone updates", () => {
|
||||
expect(r.calls).toContain(
|
||||
`docker pull registry.test/team/cms:${sha}-migrations`,
|
||||
);
|
||||
expect(r.calls).not.toContain("docker build");
|
||||
expect(r.calls).not.toMatch(/docker build\s/);
|
||||
expect(r.calls).not.toContain("docker compose build");
|
||||
expect(r.calls).toContain("target=/app/.env,readonly");
|
||||
});
|
||||
@@ -140,7 +144,13 @@ describe("Docker clone updates", () => {
|
||||
);
|
||||
expect(r.calls).toContain("https://example.test/api/health");
|
||||
expect(r.output).toContain(`Verified release ${sha}`);
|
||||
expect(r.calls).not.toContain("prune");
|
||||
// A successful update runs the scoped prune (build cache + unreferenced
|
||||
// images + stopped containers), never a global or volume prune.
|
||||
expect(r.calls).toContain("docker builder prune");
|
||||
expect(r.calls).toContain("docker image prune");
|
||||
expect(r.calls).toContain("docker container prune");
|
||||
expect(r.calls).not.toContain("docker volume prune");
|
||||
expect(r.calls).not.toContain("docker system prune");
|
||||
});
|
||||
it.each([
|
||||
"dirty",
|
||||
|
||||
Reference in new issue
Block a user