feat(docker): unify dynamic PORT across Dockerfile, compose, and dev server
This commit is contained in:
+2
-1
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user