FROM directus/directus:11.15.4 USER root # Install curl untuk health check RUN apk add --no-cache curl # ============================================ # GATEWAY SETUP (FOLDER TERPISAH - PENTING!) # ============================================ RUN mkdir -p /gateway WORKDIR /gateway # Buat package.json dengan CommonJS mode RUN echo '{"name":"gateway","type":"commonjs"}' > package.json # Install http-proxy DI SINI, bukan di /directus! RUN npm install http-proxy # Buat gateway script RUN cat > /gateway/server.js << 'GWEOF' const http = require("http"); const httpProxy = require("http-proxy"); const DOMAIN = process.env.DOMAIN || ""; const proxy = httpProxy.createProxyServer({ target: "http://127.0.0.1:8055", ws: true, changeOrigin: true }); proxy.on("error", (err, req, res) => { console.error("[Gateway Error]", err.message); if (res && res.writeHead) { res.writeHead(502, { "Content-Type": "text/plain" }); res.end("502 - Directus sedang loading..."); } }); function isAllowed(req) { if (!DOMAIN) return true; const h = [ req.headers["x-real-domain"] || "", req.headers["x-forwarded-host"] || "", req.headers["host"] || "" ].join("|"); return h.includes(DOMAIN); } const server = http.createServer((req, res) => { if (req.url === "/ping" || req.url === "/health") { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("OK"); return; } if (isAllowed(req)) { proxy.web(req, res); } else { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("OK"); } }); server.on("upgrade", (req, socket, head) => { if (isAllowed(req)) { proxy.ws(req, socket, head); } else { socket.destroy(); } }); server.listen(7860, "0.0.0.0", () => { console.log("[Gateway] Listening on :7860"); console.log("[Gateway] Proxying to Directus :8055"); if (DOMAIN) console.log("[Gateway] Domain filter:", DOMAIN); }); GWEOF # ============================================ # BRANDING FILES # ============================================ WORKDIR /directus RUN mkdir -p /directus/uploads COPY ./branding/ /directus/uploads/ # ============================================ # STARTUP SCRIPT # ============================================ RUN cat > /start.sh << 'STARTEOF' #!/bin/sh set -e echo "============================================" echo " Starting Directus (Whitelabel Edition)" echo "============================================" cd /directus # Step 1: Bootstrap (migrations + create admin) echo "[1/3] Running bootstrap..." node cli.js bootstrap 2>&1 || echo "[1/3] Bootstrap done (or skipped)" # Step 2: Start Directus echo "[2/3] Starting Directus on port 8055..." node cli.js start & # Wait for Directus to be ready echo "[2/3] Waiting for Directus..." for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do sleep 4 if curl -sf http://127.0.0.1:8055/server/ping > /dev/null 2>&1; then echo "[2/3] ✅ Directus is ready!" break fi echo "[2/3] Still waiting... ($i/15)" done # Step 3: Start Gateway echo "[3/3] Starting Gateway on port 7860..." cd /gateway exec node server.js STARTEOF RUN chmod +x /start.sh # ============================================ # FIX PERMISSIONS # ============================================ RUN chown -R node:node /gateway /start.sh /directus/uploads # ============================================ # ENVIRONMENT DEFAULTS # ============================================ ENV HOST="0.0.0.0" ENV PORT="8055" ENV LOG_LEVEL="info" ENV TELEMETRY="false" ENV CACHE_ENABLED="true" ENV RATE_LIMITER_ENABLED="false" # Whitelabel defaults (bisa override via HF Secrets) ENV PROJECT_NAME="My Custom CMS" ENV PROJECT_COLOR="#6644ff" EXPOSE 7860 USER node CMD ["/start.sh"]