added engine seperation from posts and entrypoint for compose building
This commit is contained in:
@@ -3,7 +3,7 @@ import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
test("Docker Configuration: Dockerfile enforces Node runtime and excludes Nginx", () => {
|
||||
test("Docker Configuration: Dockerfile enforces Node runtime, healthcheck, and entrypoint", () => {
|
||||
const dockerfilePath = path.resolve(process.cwd(), "Dockerfile");
|
||||
assert.ok(fs.existsSync(dockerfilePath), "Dockerfile must exist");
|
||||
|
||||
@@ -16,12 +16,32 @@ test("Docker Configuration: Dockerfile enforces Node runtime and excludes Nginx"
|
||||
assert.doesNotMatch(content, /FROM\s+nginx/i, "Dockerfile must not use nginx base image");
|
||||
assert.doesNotMatch(content, /nginx/i, "Dockerfile must not contain nginx directives");
|
||||
|
||||
// Must build static site and serve with npm
|
||||
assert.match(content, /RUN\s+npm\s+run\s+build/, "Dockerfile must run npm build");
|
||||
// Must build static site and configure dynamic port
|
||||
assert.match(content, /RUN\s+npm\s+run\s+build/, "Dockerfile must compile baseline static assets");
|
||||
assert.match(content, /ARG\s+PORT=8080/, "Dockerfile must define ARG PORT with default fallback");
|
||||
assert.match(content, /ENV\s+PORT=\$\{?PORT\}?/, "Dockerfile must define ENV PORT using variable");
|
||||
assert.match(content, /EXPOSE\s+\$\{?PORT\}?/, "Dockerfile must expose dynamic PORT variable");
|
||||
assert.match(content, /CMD\s*\[\s*["']npm["']\s*,\s*["']start["']\s*\]/, "Dockerfile must start via npm start");
|
||||
|
||||
// Must define built-in HEALTHCHECK probing 127.0.0.1 loopback
|
||||
assert.match(content, /HEALTHCHECK[\s\S]*?127\.0\.0\.1/, "Dockerfile must define baked-in HEALTHCHECK on 127.0.0.1");
|
||||
|
||||
// Must configure dynamic entrypoint script
|
||||
assert.match(content, /ENTRYPOINT\s*\[\s*["']\/app\/entrypoint\.sh["']\s*\]/, "Dockerfile must use /app/entrypoint.sh entrypoint");
|
||||
});
|
||||
|
||||
test("Docker Configuration: entrypoint.sh script exists and has valid structure", () => {
|
||||
const entrypointPath = path.resolve(process.cwd(), "entrypoint.sh");
|
||||
assert.ok(fs.existsSync(entrypointPath), "entrypoint.sh must exist");
|
||||
|
||||
const stats = fs.statSync(entrypointPath);
|
||||
// Check executable permissions (at least owner executable: 0o100)
|
||||
assert.ok(Boolean(stats.mode & 0o111), "entrypoint.sh must have executable permission bits");
|
||||
|
||||
const content = fs.readFileSync(entrypointPath, "utf-8");
|
||||
assert.match(content, /^#!\/bin\/sh/, "entrypoint.sh must use POSIX /bin/sh shebang");
|
||||
assert.match(content, /exec\s+"\$@"/, "entrypoint.sh must pass through custom container arguments");
|
||||
assert.match(content, /npm\s+run\s+build/, "entrypoint.sh must build the static site");
|
||||
assert.match(content, /exec\s+node\s+server\.js/, "entrypoint.sh must start static server with exec");
|
||||
});
|
||||
|
||||
test("Docker Configuration: docker-compose configures Node service correctly", () => {
|
||||
@@ -33,9 +53,12 @@ test("Docker Configuration: docker-compose configures Node service correctly", (
|
||||
const content = fs.readFileSync(composePath, "utf-8");
|
||||
|
||||
// Verifies dynamic port mapping and environment variables
|
||||
assert.match(content, /PORT:\s*"?\$\{PORT:-8080\}"?/, "docker-compose.yml must pass dynamic PORT build arg and env");
|
||||
assert.match(content, /PORT.*8080/, "docker-compose.yml must configure PORT fallback");
|
||||
assert.match(content, /:\$\{PORT:-8080\}/, "docker-compose.yml must map dynamic container PORT");
|
||||
|
||||
// Verifies domain argument enforcement
|
||||
assert.match(content, /SITE_DOMAIN/, "docker-compose.yml must require SITE_DOMAIN");
|
||||
|
||||
// Verifies markdown volume mount
|
||||
assert.match(content, /\/app\/src\/posts/, "docker-compose.yml must mount external markdown posts");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user