nhatrai . don't merge

This commit is contained in:
2026-05-28 16:42:34 +07:00
parent 2e6117c3a5
commit ba2a298878
6 changed files with 135 additions and 0 deletions

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
*
!nginx.conf
!docker-build-site.mjs
!www.mewedding.vn/
!www.mewedding.vn/**
!w.ladicdn.com/
!w.ladicdn.com/**

9
.env Normal file
View File

@@ -0,0 +1,9 @@
COMPOSE_PROJECT_NAME=wd-hn-nhatrai
IMAGE_NAME=toiiiiday/minhhiep-thanhnhan
IMAGE_TAG=1.0.0
CONTAINER_NAME=minhhiep-thanhnhan
HOST_PORT=7060
PUBLIC_DOMAIN=minhhiep-thanhnhan.weddinghappy.asia
SERVER_IP=172.20.235.176

17
Dockerfile Normal file
View File

@@ -0,0 +1,17 @@
FROM node:alpine AS site
WORKDIR /src
COPY docker-build-site.mjs .
COPY www.mewedding.vn ./www.mewedding.vn
COPY w.ladicdn.com ./w.ladicdn.com
RUN node docker-build-site.mjs
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=site /site/ /usr/share/nginx/html/
EXPOSE 7060
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://127.0.0.1:7060/ >/dev/null || exit 1

56
docker-build-site.mjs Normal file
View File

@@ -0,0 +1,56 @@
import fs from "node:fs/promises";
import path from "node:path";
const outDir = "/site";
const indexPath = "www.mewedding.vn/index.html";
const sourceDir = "www.mewedding.vn/source";
function decodeLocalAsset(rawUrl) {
let url = rawUrl.split("?")[0];
url = url.replaceAll("\\ ", " ");
url = url.replace(/^\.\.\//, "");
url = url.replace(/^\/+/, "");
try {
return decodeURIComponent(url);
} catch {
return url;
}
}
async function copyFilePreservingPath(relativePath) {
const source = path.resolve(relativePath);
const target = path.join(outDir, relativePath);
await fs.mkdir(path.dirname(target), { recursive: true });
await fs.copyFile(source, target);
}
const html = await fs.readFile(indexPath, "utf8");
await fs.rm(outDir, { recursive: true, force: true });
await copyFilePreservingPath(indexPath);
await fs.cp(sourceDir, path.join(outDir, sourceDir), { recursive: true });
const assetPattern =
/(?:url\(["']?|src=["']|href=["']|"(?:dC|dw)"\s*:\s*")((?:\.\.\/|\/)w\.ladicdn\.com\/[^"')]+)/g;
const assets = new Set();
for (const match of html.matchAll(assetPattern)) {
assets.add(decodeLocalAsset(match[1]));
}
const missing = [];
for (const asset of assets) {
try {
await fs.access(asset);
await copyFilePreservingPath(asset);
} catch {
missing.push(asset);
}
}
if (missing.length > 0) {
console.error("Missing local assets:");
for (const asset of missing) console.error(`- ${asset}`);
process.exit(1);
}
console.log(`Prepared static site with ${assets.size} local assets.`);

8
docker-compose.yml Normal file
View File

@@ -0,0 +1,8 @@
services:
wedding-web:
build: .
image: ${IMAGE_NAME}:${IMAGE_TAG}
container_name: ${CONTAINER_NAME}
restart: unless-stopped
ports:
- "${HOST_PORT}:7060"

38
nginx.conf Normal file
View File

@@ -0,0 +1,38 @@
server {
listen 7060;
server_name _;
root /usr/share/nginx/html;
index index.html;
charset utf-8;
add_header X-Content-Type-Options "nosniff" always;
location = / {
try_files /www.mewedding.vn/index.html =404;
}
location = /index.html {
try_files /www.mewedding.vn/index.html =404;
}
location /w.ladicdn.com/ {
try_files $uri =404;
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
}
location /www.mewedding.vn/source/ {
try_files $uri =404;
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
}
location /www.mewedding.vn/ {
try_files $uri $uri/ /www.mewedding.vn/index.html;
}
location / {
try_files $uri $uri/ /www.mewedding.vn/index.html;
}
}