feat(docker): unify dynamic PORT across Dockerfile, compose, and dev server

This commit is contained in:
venus
2026-09-13 02:04:37 -05:00
parent 78b1e0b485
commit d3aefa343e
5 changed files with 23 additions and 11 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
# River Rooks Blog Environment Template # Environment Template
# Copy to .env and adjust variables as needed: # Copy to .env and adjust variables as needed:
SITE_DOMAIN=riverrooks.dev SITE_DOMAIN=riverrooks.dev
SITE_URL=https://riverrooks.dev SITE_URL=https://riverrooks.dev
PORT=8080
+4 -3
View File
@@ -5,9 +5,10 @@ WORKDIR /app
# Dynamic build arguments & environment variables # Dynamic build arguments & environment variables
ARG SITE_DOMAIN ARG SITE_DOMAIN
ARG SITE_URL ARG SITE_URL
ARG PORT=8080
ENV SITE_DOMAIN=$SITE_DOMAIN ENV SITE_DOMAIN=$SITE_DOMAIN
ENV SITE_URL=$SITE_URL ENV SITE_URL=$SITE_URL
ENV PORT=8080 ENV PORT=$PORT
ENV NODE_ENV=production ENV NODE_ENV=production
# Install dependencies # Install dependencies
@@ -20,8 +21,8 @@ COPY . .
# Build static production assets # Build static production assets
RUN npm run build RUN npm run build
# Expose web server port # Expose web server port dynamically
EXPOSE 8080 EXPOSE ${PORT}
# Serve site with npm # Serve site with npm
CMD ["npm", "start"] CMD ["npm", "start"]
+4 -2
View File
@@ -8,16 +8,18 @@ services:
args: args:
SITE_DOMAIN: ${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env} SITE_DOMAIN: ${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env}
SITE_URL: ${SITE_URL:-https://${SITE_DOMAIN}} SITE_URL: ${SITE_URL:-https://${SITE_DOMAIN}}
PORT: ${PORT:-8080}
image: river-rooks-blog:latest image: river-rooks-blog:latest
container_name: river_rooks_web container_name: river_rooks_web
restart: unless-stopped restart: unless-stopped
environment: environment:
- SITE_DOMAIN=${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env} - SITE_DOMAIN=${SITE_DOMAIN:?Error: SITE_DOMAIN is not set. Please define SITE_DOMAIN in .env}
- SITE_URL=${SITE_URL:-https://${SITE_DOMAIN}} - SITE_URL=${SITE_URL:-https://${SITE_DOMAIN}}
- PORT=${PORT:-8080}
ports: ports:
- "8080:8080" - "${HOST_PORT:-${PORT:-8080}}:${PORT:-8080}"
healthcheck: healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"] test: ["CMD", "wget", "-qO-", "http://localhost:${PORT:-8080}/healthz"]
interval: 30s interval: 30s
timeout: 5s timeout: 5s
retries: 3 retries: 3
+5
View File
@@ -62,6 +62,11 @@ export default function (eleventyConfig) {
return [...tagSet].sort(); return [...tagSet].sort();
}); });
// 6. Dev Server Options (dynamic port binding)
eleventyConfig.setServerOptions({
port: parseInt(process.env.PORT || "8080", 10)
});
return { return {
dir: { dir: {
input: "src", input: "src",
+8 -5
View File
@@ -18,7 +18,9 @@ test("Docker Configuration: Dockerfile enforces Node runtime and excludes Nginx"
// Must build static site and serve with npm // Must build static site and serve with npm
assert.match(content, /RUN\s+npm\s+run\s+build/, "Dockerfile must run npm build"); assert.match(content, /RUN\s+npm\s+run\s+build/, "Dockerfile must run npm build");
assert.match(content, /EXPOSE\s+8080/, "Dockerfile must expose port 8080"); 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"); assert.match(content, /CMD\s*\[\s*["']npm["']\s*,\s*["']start["']\s*\]/, "Dockerfile must start via npm start");
}); });
@@ -28,11 +30,12 @@ test("Docker Configuration: docker-compose.yml configures Node service correctly
const content = fs.readFileSync(composePath, "utf-8"); const content = fs.readFileSync(composePath, "utf-8");
// Verifies port mapping to 8080 // Verifies dynamic port mapping and environment variables
assert.match(content, /8080:8080/, "docker-compose.yml must map port 8080 to container 8080"); 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 map dynamic container PORT");
// Verifies healthcheck targets 8080 // Verifies healthcheck targets dynamic port
assert.match(content, /localhost:8080/, "Healthcheck must probe port 8080"); assert.match(content, /localhost:\$\{PORT:-8080\}\/healthz/, "Healthcheck must probe dynamic PORT on /healthz");
// Verifies domain argument enforcement // Verifies domain argument enforcement
assert.match(content, /SITE_DOMAIN/, "docker-compose.yml must require SITE_DOMAIN"); assert.match(content, /SITE_DOMAIN/, "docker-compose.yml must require SITE_DOMAIN");