support arm64 reactive resume image layout
This commit is contained in:
@@ -21,16 +21,7 @@ services:
|
||||
reactive-resume:
|
||||
image: amruthpillai/reactive-resume:latest
|
||||
restart: unless-stopped
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
sh /opt/reactive-resume-patches/reactive-resume-runtime-patch.sh
|
||||
APP_DIR="$(cat /tmp/reactive-resume-app-dir 2>/dev/null || true)"
|
||||
if [ -z "$$APP_DIR" ]; then
|
||||
APP_DIR="$(find /app -path '*/.output/server/index.mjs' -type f 2>/dev/null | head -n 1 | sed 's#/.output/server/index.mjs##')"
|
||||
fi
|
||||
cd "$${APP_DIR:-/app/apps/web}"
|
||||
exec node .output/server/index.mjs
|
||||
entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"]
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
@@ -38,6 +29,7 @@ services:
|
||||
volumes:
|
||||
- reactive_resume_data:/app/data
|
||||
- ./patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
||||
- ./patches/reactive-resume-entrypoint.sh:/opt/reactive-resume-patches/reactive-resume-entrypoint.sh:ro
|
||||
networks:
|
||||
- resume_net
|
||||
depends_on:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
PATCH_SCRIPT="/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh"
|
||||
|
||||
if [ -f "$PATCH_SCRIPT" ]; then
|
||||
sh "$PATCH_SCRIPT" || echo "Reactive Resume runtime patch failed, continuing with the image default startup" >&2
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
if [ -f /app/apps/server/dist/index.mjs ]; then
|
||||
cd /app
|
||||
set -- node apps/server/dist/index.mjs
|
||||
elif [ -f /app/apps/web/.output/server/index.mjs ]; then
|
||||
cd /app/apps/web
|
||||
set -- node .output/server/index.mjs
|
||||
else
|
||||
server_entry="$(cat /tmp/reactive-resume-server-entry 2>/dev/null || true)"
|
||||
if [ -n "$server_entry" ] && [ -f "$server_entry" ]; then
|
||||
cd "$(dirname "$server_entry")"
|
||||
set -- node "$(basename "$server_entry")"
|
||||
else
|
||||
echo "Reactive Resume startup failed: no known server entry found" >&2
|
||||
find /app -maxdepth 5 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null | head -50 >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v docker-entrypoint.sh >/dev/null 2>&1; then
|
||||
exec docker-entrypoint.sh "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
@@ -2,40 +2,64 @@
|
||||
set -eu
|
||||
|
||||
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
||||
SERVER_ENTRY=""
|
||||
ASSETS_DIR=""
|
||||
SSR_DIR=""
|
||||
SERVER_INDEX_FILE=""
|
||||
SSR_FILE=""
|
||||
|
||||
if [ -z "$APP_DIR" ]; then
|
||||
for candidate in /app/apps/web /app; do
|
||||
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
||||
APP_DIR="$candidate"
|
||||
SERVER_ENTRY="$candidate/.output/server/index.mjs"
|
||||
ASSETS_DIR="$candidate/.output/public/assets"
|
||||
SSR_DIR="$candidate/.output/server/_ssr"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$APP_DIR" ]; then
|
||||
if [ -z "$SERVER_ENTRY" ]; then
|
||||
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
||||
if [ -n "$index_file" ]; then
|
||||
APP_DIR="${index_file%/.output/server/index.mjs}"
|
||||
SERVER_ENTRY="$index_file"
|
||||
ASSETS_DIR="$APP_DIR/.output/public/assets"
|
||||
SSR_DIR="$APP_DIR/.output/server/_ssr"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$APP_DIR" ] || [ ! -f "$APP_DIR/.output/server/index.mjs" ]; then
|
||||
echo "Reactive Resume runtime patch skipped: .output/server/index.mjs not found under /app" >&2
|
||||
if [ -z "$SERVER_ENTRY" ] && [ -f /app/apps/server/dist/index.mjs ]; then
|
||||
APP_DIR="/app"
|
||||
SERVER_ENTRY="/app/apps/server/dist/index.mjs"
|
||||
ASSETS_DIR="/app/apps/web/dist/assets"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
SSR_FILE="$SERVER_ENTRY"
|
||||
fi
|
||||
|
||||
if [ -z "$SERVER_ENTRY" ] || [ ! -f "$SERVER_ENTRY" ]; then
|
||||
echo "Reactive Resume runtime patch skipped: server entry not found under /app" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
||||
export APP_DIR
|
||||
printf "%s" "$SERVER_ENTRY" > /tmp/reactive-resume-server-entry
|
||||
export APP_DIR ASSETS_DIR SSR_DIR SERVER_INDEX_FILE SSR_FILE SERVER_ENTRY
|
||||
|
||||
node - <<'NODE'
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const appDir = process.env.APP_DIR;
|
||||
const appDir = process.env.APP_DIR || "/app";
|
||||
const outputDir = path.join(appDir, ".output");
|
||||
const assetsDir = path.join(outputDir, "public/assets");
|
||||
const ssrDir = path.join(outputDir, "server/_ssr");
|
||||
const serverIndexFile = path.join(outputDir, "server/index.mjs");
|
||||
const assetsDir = process.env.ASSETS_DIR || path.join(outputDir, "public/assets");
|
||||
const ssrDir = process.env.SSR_DIR || "";
|
||||
const explicitSsrFile = process.env.SSR_FILE || "";
|
||||
const serverIndexFile = process.env.SERVER_INDEX_FILE || path.join(outputDir, "server/index.mjs");
|
||||
const filenameCacheBust = "rr-filename-title-20260520";
|
||||
const pdfCacheBust = "rr-glalie-layout-20260520";
|
||||
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
||||
@@ -117,12 +141,17 @@ function patchSsr(source) {
|
||||
|
||||
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
||||
if (!source.includes(filenameReplacement)) {
|
||||
const start = source.indexOf("function generateFilename(");
|
||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||
if (start !== -1 && end !== -1) {
|
||||
source = source.slice(0, start) + filenameReplacement + source.slice(end);
|
||||
const slugifiedPattern = /function generateFilename\(prefix, extension\) \{\s*return `\$\{slugify\(prefix\)\}\$\{extension \? `\.\$\{extension\}` : ""\}`;\s*\}/;
|
||||
if (slugifiedPattern.test(source)) {
|
||||
source = source.replace(slugifiedPattern, filenameReplacement);
|
||||
} else {
|
||||
warn("SSR generateFilename marker not found, skipped");
|
||||
const start = source.indexOf("function generateFilename(");
|
||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||
if (start !== -1 && end !== -1) {
|
||||
source = source.slice(0, start) + filenameReplacement + source.slice(end);
|
||||
} else {
|
||||
warn("SSR generateFilename marker not found, skipped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +184,8 @@ function patchSsr(source) {
|
||||
|
||||
function patchPublicPdf(source) {
|
||||
if (!source.includes("rr-browser-buffer-polyfill")) {
|
||||
const insertAt = source.indexOf(";") + 1;
|
||||
const importPrelude = source.match(/^(?:import[^;]+;)+/);
|
||||
const insertAt = importPrelude ? importPrelude[0].length : source.indexOf(";") + 1;
|
||||
if (insertAt > 0 && source.startsWith("import")) {
|
||||
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
||||
} else {
|
||||
@@ -193,7 +223,9 @@ for (const file of filenameFiles) {
|
||||
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
||||
|
||||
let ssrFile = "";
|
||||
if (fs.existsSync(ssrDir)) {
|
||||
if (explicitSsrFile && fs.existsSync(explicitSsrFile) && read(explicitSsrFile).includes("function generateFilename(")) {
|
||||
ssrFile = explicitSsrFile;
|
||||
} else if (ssrDir && fs.existsSync(ssrDir)) {
|
||||
ssrFile = fs.readdirSync(ssrDir)
|
||||
.filter((name) => name.endsWith(".mjs"))
|
||||
.map((name) => path.join(ssrDir, name))
|
||||
|
||||
@@ -44,16 +44,7 @@ services:
|
||||
reactive_resume_app:
|
||||
image: amruthpillai/reactive-resume:latest
|
||||
restart: unless-stopped
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
sh /opt/reactive-resume-patches/reactive-resume-runtime-patch.sh
|
||||
APP_DIR="$(cat /tmp/reactive-resume-app-dir 2>/dev/null || true)"
|
||||
if [ -z "$$APP_DIR" ]; then
|
||||
APP_DIR="$(find /app -path '*/.output/server/index.mjs' -type f 2>/dev/null | head -n 1 | sed 's#/.output/server/index.mjs##')"
|
||||
fi
|
||||
cd "$${APP_DIR:-/app/apps/web}"
|
||||
exec node .output/server/index.mjs
|
||||
entrypoint: ["/bin/sh", "/opt/reactive-resume-patches/reactive-resume-entrypoint.sh"]
|
||||
depends_on:
|
||||
reactive_resume_permissions:
|
||||
condition: service_completed_successfully
|
||||
@@ -64,6 +55,7 @@ services:
|
||||
volumes:
|
||||
- /share/Container/reactive_resume/data/uploads:/app/data
|
||||
- /share/Container/reactive_resume/patches/reactive-resume-runtime-patch.sh:/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh:ro
|
||||
- /share/Container/reactive_resume/patches/reactive-resume-entrypoint.sh:/opt/reactive-resume-patches/reactive-resume-entrypoint.sh:ro
|
||||
environment:
|
||||
HTTP_PROXY: http://192.168.3.12:7893
|
||||
HTTPS_PROXY: http://192.168.3.12:7893
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
PATCH_SCRIPT="/opt/reactive-resume-patches/reactive-resume-runtime-patch.sh"
|
||||
|
||||
if [ -f "$PATCH_SCRIPT" ]; then
|
||||
sh "$PATCH_SCRIPT" || echo "Reactive Resume runtime patch failed, continuing with the image default startup" >&2
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
if [ -f /app/apps/server/dist/index.mjs ]; then
|
||||
cd /app
|
||||
set -- node apps/server/dist/index.mjs
|
||||
elif [ -f /app/apps/web/.output/server/index.mjs ]; then
|
||||
cd /app/apps/web
|
||||
set -- node .output/server/index.mjs
|
||||
else
|
||||
server_entry="$(cat /tmp/reactive-resume-server-entry 2>/dev/null || true)"
|
||||
if [ -n "$server_entry" ] && [ -f "$server_entry" ]; then
|
||||
cd "$(dirname "$server_entry")"
|
||||
set -- node "$(basename "$server_entry")"
|
||||
else
|
||||
echo "Reactive Resume startup failed: no known server entry found" >&2
|
||||
find /app -maxdepth 5 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null | head -50 >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v docker-entrypoint.sh >/dev/null 2>&1; then
|
||||
exec docker-entrypoint.sh "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
@@ -2,40 +2,64 @@
|
||||
set -eu
|
||||
|
||||
APP_DIR="${REACTIVE_RESUME_APP_DIR:-}"
|
||||
SERVER_ENTRY=""
|
||||
ASSETS_DIR=""
|
||||
SSR_DIR=""
|
||||
SERVER_INDEX_FILE=""
|
||||
SSR_FILE=""
|
||||
|
||||
if [ -z "$APP_DIR" ]; then
|
||||
for candidate in /app/apps/web /app; do
|
||||
if [ -f "$candidate/.output/server/index.mjs" ]; then
|
||||
APP_DIR="$candidate"
|
||||
SERVER_ENTRY="$candidate/.output/server/index.mjs"
|
||||
ASSETS_DIR="$candidate/.output/public/assets"
|
||||
SSR_DIR="$candidate/.output/server/_ssr"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$APP_DIR" ]; then
|
||||
if [ -z "$SERVER_ENTRY" ]; then
|
||||
index_file="$(find /app -path "*/.output/server/index.mjs" -type f 2>/dev/null | head -n 1 || true)"
|
||||
if [ -n "$index_file" ]; then
|
||||
APP_DIR="${index_file%/.output/server/index.mjs}"
|
||||
SERVER_ENTRY="$index_file"
|
||||
ASSETS_DIR="$APP_DIR/.output/public/assets"
|
||||
SSR_DIR="$APP_DIR/.output/server/_ssr"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$APP_DIR" ] || [ ! -f "$APP_DIR/.output/server/index.mjs" ]; then
|
||||
echo "Reactive Resume runtime patch skipped: .output/server/index.mjs not found under /app" >&2
|
||||
if [ -z "$SERVER_ENTRY" ] && [ -f /app/apps/server/dist/index.mjs ]; then
|
||||
APP_DIR="/app"
|
||||
SERVER_ENTRY="/app/apps/server/dist/index.mjs"
|
||||
ASSETS_DIR="/app/apps/web/dist/assets"
|
||||
SERVER_INDEX_FILE="$SERVER_ENTRY"
|
||||
SSR_FILE="$SERVER_ENTRY"
|
||||
fi
|
||||
|
||||
if [ -z "$SERVER_ENTRY" ] || [ ! -f "$SERVER_ENTRY" ]; then
|
||||
echo "Reactive Resume runtime patch skipped: server entry not found under /app" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf "%s" "$APP_DIR" > /tmp/reactive-resume-app-dir
|
||||
export APP_DIR
|
||||
printf "%s" "$SERVER_ENTRY" > /tmp/reactive-resume-server-entry
|
||||
export APP_DIR ASSETS_DIR SSR_DIR SERVER_INDEX_FILE SSR_FILE SERVER_ENTRY
|
||||
|
||||
node - <<'NODE'
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const appDir = process.env.APP_DIR;
|
||||
const appDir = process.env.APP_DIR || "/app";
|
||||
const outputDir = path.join(appDir, ".output");
|
||||
const assetsDir = path.join(outputDir, "public/assets");
|
||||
const ssrDir = path.join(outputDir, "server/_ssr");
|
||||
const serverIndexFile = path.join(outputDir, "server/index.mjs");
|
||||
const assetsDir = process.env.ASSETS_DIR || path.join(outputDir, "public/assets");
|
||||
const ssrDir = process.env.SSR_DIR || "";
|
||||
const explicitSsrFile = process.env.SSR_FILE || "";
|
||||
const serverIndexFile = process.env.SERVER_INDEX_FILE || path.join(outputDir, "server/index.mjs");
|
||||
const filenameCacheBust = "rr-filename-title-20260520";
|
||||
const pdfCacheBust = "rr-glalie-layout-20260520";
|
||||
const browserBufferPolyfill = "var Buffer=globalThis.Buffer??{isBuffer:()=>false,allocUnsafe:e=>new Uint8Array(e),alloc:e=>new Uint8Array(e)};/* rr-browser-buffer-polyfill */";
|
||||
@@ -117,12 +141,17 @@ function patchSsr(source) {
|
||||
|
||||
const filenameReplacement = `function generateFilename(prefix, extension) {\n\tlet filename = (prefix || "resume").toString().trim() || "resume";\n\tfilename = filename.replace(/[\\\\/:*?"<>|]/g, "-").replace(/\\s+/g, " ").replace(/\\.+$/, "").trim() || "resume";\n\treturn extension && filename.toLowerCase().endsWith(\`.\${extension.toLowerCase()}\`) ? filename : \`\${filename}\${extension ? \`.\${extension}\` : ""}\`;\n}`;
|
||||
if (!source.includes(filenameReplacement)) {
|
||||
const start = source.indexOf("function generateFilename(");
|
||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||
if (start !== -1 && end !== -1) {
|
||||
source = source.slice(0, start) + filenameReplacement + source.slice(end);
|
||||
const slugifiedPattern = /function generateFilename\(prefix, extension\) \{\s*return `\$\{slugify\(prefix\)\}\$\{extension \? `\.\$\{extension\}` : ""\}`;\s*\}/;
|
||||
if (slugifiedPattern.test(source)) {
|
||||
source = source.replace(slugifiedPattern, filenameReplacement);
|
||||
} else {
|
||||
warn("SSR generateFilename marker not found, skipped");
|
||||
const start = source.indexOf("function generateFilename(");
|
||||
const end = source.indexOf("\nfunction downloadWithAnchor(", start);
|
||||
if (start !== -1 && end !== -1) {
|
||||
source = source.slice(0, start) + filenameReplacement + source.slice(end);
|
||||
} else {
|
||||
warn("SSR generateFilename marker not found, skipped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +184,8 @@ function patchSsr(source) {
|
||||
|
||||
function patchPublicPdf(source) {
|
||||
if (!source.includes("rr-browser-buffer-polyfill")) {
|
||||
const insertAt = source.indexOf(";") + 1;
|
||||
const importPrelude = source.match(/^(?:import[^;]+;)+/);
|
||||
const insertAt = importPrelude ? importPrelude[0].length : source.indexOf(";") + 1;
|
||||
if (insertAt > 0 && source.startsWith("import")) {
|
||||
source = source.slice(0, insertAt) + browserBufferPolyfill + source.slice(insertAt);
|
||||
} else {
|
||||
@@ -193,7 +223,9 @@ for (const file of filenameFiles) {
|
||||
if (patchedFilenameFiles.length === 0) warn("no filename bundle patched");
|
||||
|
||||
let ssrFile = "";
|
||||
if (fs.existsSync(ssrDir)) {
|
||||
if (explicitSsrFile && fs.existsSync(explicitSsrFile) && read(explicitSsrFile).includes("function generateFilename(")) {
|
||||
ssrFile = explicitSsrFile;
|
||||
} else if (ssrDir && fs.existsSync(ssrDir)) {
|
||||
ssrFile = fs.readdirSync(ssrDir)
|
||||
.filter((name) => name.endsWith(".mjs"))
|
||||
.map((name) => path.join(ssrDir, name))
|
||||
|
||||
Reference in New Issue
Block a user