Compare commits

4 Commits

Author SHA1 Message Date
9ccbb54a58 Sửa ngày 2026-05-29 09:52:35 +07:00
1bf394cc1d update 2026-05-29 09:39:46 +07:00
ba2a298878 nhatrai . don't merge 2026-05-28 16:42:34 +07:00
2e6117c3a5 sửa cho nhà trai 2026-05-28 16:20:38 +07:00
8 changed files with 219 additions and 32 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

View File

@@ -5,18 +5,18 @@ Website tĩnh (Ladipage). Cần chạy qua **web server cục bộ** — không
## Cách nhanh nhất
1. Double-click file **`start.bat`** trong thư mục dự án.
2. Trình duyệt sẽ mở: `http://localhost:8080/www.mewedding.vn/index.html`
2. Trình duyệt sẽ mở: `http://localhost:8888/www.mewedding.vn/index.html`
3. Dừng server: nhấn `Ctrl+C` trong cửa sổ đen (hoặc đóng cửa sổ).
## Mở qua WiFi (điện thoại / máy khác cùng mạng)
1. Máy tính và điện thoại **cùng WiFi** (không dùng guest network chặn LAN).
2. Chạy **`start.bat`** — cửa sổ PowerShell in thêm dòng dạng:
`http://192.168.x.x:8080/www.mewedding.vn/index.html`
`http://192.168.x.x:8888/www.mewedding.vn/index.html`
3. Trên điện thoại, mở đúng URL đó (thay `192.168.x.x` bằng IP hiện in ra).
4. **Điện thoại không vào được** (hay gặp nhất):
- Chạy lại **`setup-wifi.ps1`** (Admin) — script mở **firewall cổng 8080** và đặt Wi-Fi sang **Private**.
- Trên điện thoại dùng đúng URL dòng **`>>> DIEN THOAI`** (thường `http://192.168.1.x:8080/...`), không dùng `localhost`.
- Chạy lại **`setup-wifi.ps1`** (Admin) — script mở **firewall cổng 8888** và đặt Wi-Fi sang **Private**.
- Trên điện thoại dùng đúng URL dòng **`>>> DIEN THOAI`** (thường `http://192.168.1.x:8888/...`), không dùng `localhost`.
- Điện thoại **tắt 4G/5G**, chỉ dùng WiFi cùng nhà; tắt VPN trên PC/điện thoại.
- Router: tắt **AP isolation / client isolation** nếu bật.
- Cửa sổ `start.bat` có dòng `192.168.x.x -> ...` khi điện thoại truy cập → server nhận được; không có dòng → firewall/router chặn.
@@ -28,9 +28,9 @@ Website tĩnh (Ladipage). Cần chạy qua **web server cục bộ** — không
```
Hoặc lệnh tay (**không** dùng `%USERNAME%` trong PowerShell — sẽ lỗi 1332):
```powershell
netsh http add urlacl url=http://+:8080/ user="$env:USERDOMAIN\$env:USERNAME"
netsh http add urlacl url=http://+:8888/ user="$env:USERDOMAIN\$env:USERNAME"
```
Trong **CMD (Admin)** thì dùng được: `netsh http add urlacl url=http://+:8080/ user=%USERNAME%`
Trong **CMD (Admin)** thì dùng được: `netsh http add urlacl url=http://+:8888/ user=%USERNAME%`
## Chạy bằng PowerShell

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;
}
}

View File

@@ -14,7 +14,7 @@
<meta property="og:type" content="website" />
<meta property="og:title" content="Thiệp mời Hiệp & Nhàn" />
<meta property="og:description"
content="Trân trọng kính mời bạn đến dự lễ cưới của Hiệp & Nhàn — lúc 17:00 ngày 06/06/2026. Nhấn để xem chi tiết!" />
content="Trân trọng kính mời bạn đến dự lễ cưới của Hiệp & Nhàn — lúc 10:00 ngày 07/06/2026. Nhấn để xem chi tiết!" />
<meta property="og:url" content="https://minhhiep.weddinghappy.asia/" />
<link rel="dns-prefetch">
<link rel="preconnect" href="https://fonts.googleapis.com/" crossorigin>
@@ -3630,6 +3630,40 @@
text-align: center;
}
#PARAGRAPH124 .parent-lines,
#PARAGRAPH126 .parent-lines {
display: inline-block;
text-align: left;
vertical-align: top;
}
#PARAGRAPH124 .parent-line,
#PARAGRAPH126 .parent-line {
display: flex;
align-items: flex-start;
gap: 6px;
margin: 0 0 4px;
}
#PARAGRAPH124 .parent-line:last-child,
#PARAGRAPH126 .parent-line:last-child {
margin-bottom: 0;
}
#PARAGRAPH124 .parent-label,
#PARAGRAPH126 .parent-label {
flex: 0 0 68px;
text-align: right;
font-weight: 400;
}
#PARAGRAPH124 .parent-name,
#PARAGRAPH126 .parent-name {
flex: 1 1 auto;
font-weight: 700;
text-align: left;
}
#GROUP105 {
width: 217px;
height: 305.335px;
@@ -4235,8 +4269,8 @@
#SHAPE87 {
width: 28px;
height: 26px;
top: 187.47px;
left: 304.523px;
top: 187.67px;
left: 361.203px;
z-index: 1;
}
@@ -4415,6 +4449,16 @@
#PARAGRAPH194 {
top: 187.67px;
left: 361.203px;
z-index: 2;
}
#PARAGRAPH194>.ladi-paragraph {
width: 28px;
height: 26px;
line-height: 26px;
color: rgb(255, 255, 255);
font-weight: 700;
text-align: center;
}
#PARAGRAPH195 {
@@ -7102,7 +7146,7 @@
</div>
</div>
<div id="HEADLINE8" class='ladi-element'>
<h3 class='ladi-headline ladi-transition'>06.06.2026<br></h3>
<h3 class='ladi-headline ladi-transition'>07.06.2026<br></h3>
</div>
<div id="IMAGE15" class='ladi-element'>
<div class='ladi-image'>
@@ -7158,13 +7202,13 @@
<div id="GROUP12" class='ladi-element'>
<div class='ladi-group'>
<div id="PARAGRAPH11" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>17 GIỜ 00<br></div>
<div class='ladi-paragraph ladi-transition'>10 GIỜ 00<br></div>
</div>
<div id="PARAGRAPH12" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>06</div>
<div class='ladi-paragraph ladi-transition'>07</div>
</div>
<div id="PARAGRAPH13" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>( Nhằm ngày 21 tháng 04 năm Bính Ngọ. )</div>
<div class='ladi-paragraph ladi-transition'>( Nhằm ngày 22 tháng 04 năm Bính Ngọ. )</div>
</div>
<div id="LINE5" class='ladi-element'>
<div class='ladi-line'>
@@ -7172,7 +7216,7 @@
</div>
</div>
<div id="PARAGRAPH14" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>THỨ BẢY<br></div>
<div class='ladi-paragraph ladi-transition'>CHỦ NHẬT<br></div>
</div>
<div id="PARAGRAPH15" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>06 - 2026<br></div>
@@ -7187,7 +7231,7 @@
</div>
</div>
<div id="HEADLINE28" class='ladi-element'>
<h3 class='ladi-headline ladi-transition'>Tại : Trường THCS Trung Môn<br>TDP 5, P.Trung Môn, Tỉnh Tuyên Quang<br></h3>
<h3 class='ladi-headline ladi-transition'>Tại : Trường Tiểu Học Nông Tiến <br>TDP 7, P.Nông Tiến, Tỉnh Tuyên Quang<br></h3>
</div>
<div id="HEADLINE29" class='ladi-element'>
<h3 class='ladi-headline ladi-transition'>Sự hiện diện của quý khách là niềm vinh dự cho gia đình
@@ -7204,7 +7248,7 @@
<h3 class='ladi-headline ladi-transition'>SAVE THE DATE<br></h3>
</div>
<div id="HEADLINE113" class='ladi-element'>
<h3 class='ladi-headline ladi-transition'>Bạn và người thương</h3>
<h3 class='ladi-headline ladi-transition'>Quý hách</h3>
</div>
</div>
</div>
@@ -7251,8 +7295,12 @@
</div>
</div>
<div id="PARAGRAPH124" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>Con ông : <span style="font-weight: 700;">Lê Tiến Lực
</span><br>Con bà : <span style="font-weight: 700;">Mai Thị Thanh Tùng</span><br></div>
<div class='ladi-paragraph ladi-transition'>
<div class="parent-lines">
<div class="parent-line"><span class="parent-label">Con ông :</span><span class="parent-name">Lê Tiến Lực</span></div>
<div class="parent-line"><span class="parent-label">Con bà :</span><span class="parent-name">Mai Thị Thanh Tùng</span></div>
</div>
</div>
</div>
</div>
</div>
@@ -7286,8 +7334,12 @@
</div>
</div>
<div id="PARAGRAPH126" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>Con ông : <span style="font-weight: 700;">Phùng Quốc Lập
</span><br>Con bà : <span style="font-weight: 700;">Nguyễn Thị Thu Hà</span><br></div>
<div class='ladi-paragraph ladi-transition'>
<div class="parent-lines">
<div class="parent-line"><span class="parent-label">Con ông :</span><span class="parent-name">Phùng Quốc Lập</span></div>
<div class="parent-line"><span class="parent-label">Con bà :</span><span class="parent-name">Nguyễn Thị Thu Hà</span></div>
</div>
</div>
</div>
</div>
</div>
@@ -7453,7 +7505,7 @@
</div>
</div>
<div id="PARAGRAPH178" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>17:00 Thứ Bảy, ngày 06/06/2026<br>(Tức ngày 21/04 Bính Ngọ)<br></div>
<div class='ladi-paragraph ladi-transition'>10:00 Chủ Nhật, ngày 07/06/2026<br>(Tức ngày 22/04 Bính Ngọ)<br></div>
</div>
<div id="GROUP179" class='ladi-element'>
<div class='ladi-group'>
@@ -8387,7 +8439,7 @@
<p class='ladi-headline'>Xác nhận tham dự</p>
</div>
</div>
</div><a href="https://maps.app.goo.gl/mS1FLoDDXzJCimX47" target="_blank" id="BUTTON44"
</div><a href="https://maps.app.goo.gl/5a5dP4gb2upZwKxm7" target="_blank" id="BUTTON44"
class='ladi-element'>
<div class='ladi-button ladi-transition'>
<div class="ladi-button-background"></div>
@@ -8401,7 +8453,7 @@
<div id="GROUP176" class='ladi-element'>
<div class='ladi-group'>
<div id="PARAGRAPH170" class='ladi-element'>
<div class='ladi-paragraph'>17:00 Thứ Bảy, ngày 06-06-2026</div>
<div class='ladi-paragraph'>10:00 Chủ Nhật, ngày 07-06-2026</div>
</div>
<div id="SHAPE83" class='ladi-element'>
<div class='ladi-shape'><svg xmlns="http://www.w3.org/2000/svg"
@@ -8416,8 +8468,8 @@
<div id="GROUP173" class='ladi-element'>
<div class='ladi-group'>
<div id="PARAGRAPH171" class='ladi-element'>
<div class='ladi-paragraph'>Tại : Trường THCS Trung Môn
<br>TDP Trung Môn 5, P.Minh Xuân, Tỉnh Tuyên Quang<br>
<div class='ladi-paragraph'>Tại : Trường Tiểu Học Nông Tiến
<br>TDP 7, P.Nông Tiến, Tỉnh Tuyên Quang<br>
</div>
</div>
<div id="SHAPE84" class='ladi-element'>
@@ -8443,7 +8495,7 @@
</div>
</div>
<div id="HEADLINE112" class='ladi-element'>
<h3 class='ladi-headline ladi-transition'>Lễ Vu Quy<br></h3>
<h3 class='ladi-headline ladi-transition'>Lễ Thành Hôn<br></h3>
</div>
<div data-action="true" id="GROUP172" class='ladi-element'>
<div class='ladi-group'>
@@ -8454,7 +8506,7 @@
<p class='ladi-headline'>Xác nhận tham dự</p>
</div>
</div>
</div><a href="https://maps.app.goo.gl/oa1HDQ8C5rfco4nw7" target="_blank" id="BUTTON46"
</div><a href="https://maps.app.goo.gl/ndRuG3NDngmGL6g89" target="_blank" id="BUTTON46"
class='ladi-element'>
<div class='ladi-button ladi-transition'>
<div class="ladi-button-background"></div>
@@ -8468,7 +8520,7 @@
<div id="GROUP175" class='ladi-element'>
<div class='ladi-group'>
<div id="PARAGRAPH172" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>07:30 Chủ Nhật, ngày 07-06-2026</div>
<div class='ladi-paragraph ladi-transition'>10:00 Chủ Nhật, ngày 07-06-2026</div>
</div>
<div id="SHAPE85" class='ladi-element'>
<div class='ladi-shape ladi-transition'><svg xmlns="http://www.w3.org/2000/svg"
@@ -8483,8 +8535,8 @@
<div id="GROUP174" class='ladi-element'>
<div class='ladi-group'>
<div id="PARAGRAPH173" class='ladi-element'>
<div class='ladi-paragraph ladi-transition'>Tại : Tư Gia Nhà i
<br>Quầy thuốc số 18, Quốc lộ 2, P.Minh Xuân, Tỉnh Tuyên Quang<br>
<div class='ladi-paragraph ladi-transition'>Tại : Tư Gia Nhà Trai
<br>Số 152, đường Tân Trào, P.Nông Tiến, Tỉnh Tuyên Quang<br>
</div>
</div>
<div id="SHAPE86" class='ladi-element'>
@@ -10774,8 +10826,8 @@
<script>
(function () {
// 17:00 +07:00 ngày 06/06/2026 tương đương 10:00:00 UTC cùng ngày
var targetUTC = Date.UTC(2026, 5, 6, 10, 0, 0); // Tháng 0-based: 5 = Tháng 6
// 10:00 +07:00 ngày 07/06/2026 tương đương 03:00:00 UTC cùng ngày
var targetUTC = Date.UTC(2026, 5, 7, 3, 0, 0); // Tháng 0-based: 5 = Tháng 6
function pad2(n) { return (n < 10 ? '0' : '') + n; }