mirror of
https://github.com/umami-software/umami.git
synced 2025-12-06 01:18:00 +01:00
Fixed docker build.
This commit is contained in:
parent
e7f565f143
commit
dbc9525c9c
5 changed files with 76 additions and 88 deletions
|
|
@ -4,4 +4,6 @@ Dockerfile
|
||||||
.gitignore
|
.gitignore
|
||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
.idea
|
.idea
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ FROM node:22-alpine AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
|
COPY docker/middleware.ts ./src
|
||||||
|
|
||||||
ARG DATABASE_TYPE
|
ARG DATABASE_TYPE
|
||||||
ARG BASE_PATH
|
ARG BASE_PATH
|
||||||
|
|
@ -41,7 +42,7 @@ RUN set -x \
|
||||||
&& apk add --no-cache curl
|
&& apk add --no-cache curl
|
||||||
|
|
||||||
# Script dependencies
|
# Script dependencies
|
||||||
RUN pnpm add npm-run-all dotenv prisma@6.8.2
|
RUN pnpm add npm-run-all dotenv chalk semver prisma@6.16.0 @prisma/adapter-pg@6.16.0
|
||||||
|
|
||||||
# Permissions for prisma
|
# Permissions for prisma
|
||||||
RUN chown -R nextjs:nodejs node_modules/.pnpm/
|
RUN chown -R nextjs:nodejs node_modules/.pnpm/
|
||||||
|
|
@ -49,15 +50,13 @@ RUN chown -R nextjs:nodejs node_modules/.pnpm/
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
|
||||||
COPY --from=builder /app/prisma ./prisma
|
COPY --from=builder /app/prisma ./prisma
|
||||||
COPY --from=builder /app/scripts ./scripts
|
COPY --from=builder /app/scripts ./scripts
|
||||||
|
COPY --from=builder /app/generated ./generated
|
||||||
|
|
||||||
# Automatically leverage output traces to reduce image size
|
# Automatically leverage output traces to reduce image size
|
||||||
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
# Custom routes
|
|
||||||
RUN mv ./.next/routes-manifest.json ./.next/routes-manifest-orig.json
|
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
|
||||||
69
docker/middleware.ts
Normal file
69
docker/middleware.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { NextRequest, NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: '/:path*',
|
||||||
|
};
|
||||||
|
|
||||||
|
const TRACKER_NAME = '/script.js';
|
||||||
|
const COLLECT_ENDPOINT = '/api/send';
|
||||||
|
|
||||||
|
const apiHeaders = {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'Access-Control-Allow-Headers': '*',
|
||||||
|
'Access-Control-Allow-Methods': 'GET, DELETE, POST, PUT',
|
||||||
|
'Access-Control-Max-Age': process.env.CORS_MAX_AGE || '86400',
|
||||||
|
'Cache-Control': 'no-cache',
|
||||||
|
};
|
||||||
|
|
||||||
|
const trackerHeaders = {
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
'Cache-Control': 'public, max-age=86400, must-revalidate',
|
||||||
|
};
|
||||||
|
|
||||||
|
function customCollectEndpoint(request: NextRequest) {
|
||||||
|
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
|
||||||
|
|
||||||
|
if (collectEndpoint) {
|
||||||
|
const url = request.nextUrl.clone();
|
||||||
|
|
||||||
|
if (url.pathname.endsWith(collectEndpoint)) {
|
||||||
|
url.pathname = COLLECT_ENDPOINT;
|
||||||
|
return NextResponse.rewrite(url, { headers: apiHeaders });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function customScriptName(request: NextRequest) {
|
||||||
|
const scriptName = process.env.TRACKER_SCRIPT_NAME;
|
||||||
|
|
||||||
|
if (scriptName) {
|
||||||
|
const url = request.nextUrl.clone();
|
||||||
|
const names = scriptName.split(',').map(name => name.trim().replace(/^\/+/, ''));
|
||||||
|
|
||||||
|
if (names.find(name => url.pathname.endsWith(name))) {
|
||||||
|
url.pathname = TRACKER_NAME;
|
||||||
|
return NextResponse.rewrite(url, { headers: trackerHeaders });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function customScriptUrl(request: NextRequest) {
|
||||||
|
const scriptUrl = process.env.TRACKER_SCRIPT_URL;
|
||||||
|
|
||||||
|
if (scriptUrl && request.nextUrl.pathname.endsWith(TRACKER_NAME)) {
|
||||||
|
return NextResponse.rewrite(scriptUrl, { headers: trackerHeaders });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function middleware(req: NextRequest) {
|
||||||
|
const fns = [customCollectEndpoint, customScriptName, customScriptUrl];
|
||||||
|
|
||||||
|
for (const fn of fns) {
|
||||||
|
const res = fn(req);
|
||||||
|
if (res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.next();
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
|
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
|
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
|
||||||
"start-docker": "npm-run-all check-db update-tracker set-routes-manifest start-server",
|
"start-docker": "npm-run-all check-db update-tracker start-server",
|
||||||
"start-env": "node scripts/start-env.js",
|
"start-env": "node scripts/start-env.js",
|
||||||
"start-server": "node server.js",
|
"start-server": "node server.js",
|
||||||
"build-app": "next build --turbo",
|
"build-app": "next build --turbo",
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
"build-db": "npm-run-all build-db-client build-prisma-client",
|
"build-db": "npm-run-all build-db-client build-prisma-client",
|
||||||
"build-db-schema": "prisma db pull",
|
"build-db-schema": "prisma db pull",
|
||||||
"build-db-client": "prisma generate",
|
"build-db-client": "prisma generate",
|
||||||
"set-routes-manifest": "node scripts/set-routes-manifest.js",
|
|
||||||
"update-tracker": "node scripts/update-tracker.js",
|
"update-tracker": "node scripts/update-tracker.js",
|
||||||
"update-db": "prisma migrate deploy",
|
"update-db": "prisma migrate deploy",
|
||||||
"check-db": "node scripts/check-db.js",
|
"check-db": "node scripts/check-db.js",
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
/* eslint-disable no-console */
|
|
||||||
import 'dotenv/config';
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import path from 'node:path';
|
|
||||||
import { createRequire } from 'module';
|
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
|
||||||
|
|
||||||
const routesManifestPath = path.resolve(process.cwd(), '.next/routes-manifest.json');
|
|
||||||
const originalPath = path.resolve(process.cwd(), '.next/routes-manifest-orig.json');
|
|
||||||
const originalManifest = require(originalPath);
|
|
||||||
|
|
||||||
const basePath = originalManifest.basePath;
|
|
||||||
|
|
||||||
const API_PATH = basePath + '/api/:path*';
|
|
||||||
const TRACKER_SCRIPT = basePath + '/script.js';
|
|
||||||
|
|
||||||
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT;
|
|
||||||
const trackerScriptName = process.env.TRACKER_SCRIPT_NAME;
|
|
||||||
|
|
||||||
const headers = [];
|
|
||||||
const rewrites = [];
|
|
||||||
|
|
||||||
if (collectApiEndpoint) {
|
|
||||||
const apiRoute = originalManifest.headers.find(route => route.source === API_PATH);
|
|
||||||
const routeRegex = new RegExp(apiRoute.regex);
|
|
||||||
|
|
||||||
const normalizedSource = basePath + collectApiEndpoint;
|
|
||||||
|
|
||||||
rewrites.push({
|
|
||||||
source: normalizedSource,
|
|
||||||
destination: basePath + '/api/send',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!routeRegex.test(normalizedSource)) {
|
|
||||||
headers.push({
|
|
||||||
source: normalizedSource,
|
|
||||||
headers: apiRoute.headers,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackerScriptName) {
|
|
||||||
const trackerRoute = originalManifest.headers.find(route => route.source === TRACKER_SCRIPT);
|
|
||||||
|
|
||||||
const names = trackerScriptName?.split(',').map(name => name.trim());
|
|
||||||
|
|
||||||
if (names) {
|
|
||||||
names.forEach(name => {
|
|
||||||
const normalizedSource = `${basePath}/${name.replace(/^\/+/, '')}`;
|
|
||||||
|
|
||||||
rewrites.push({
|
|
||||||
source: normalizedSource,
|
|
||||||
destination: TRACKER_SCRIPT,
|
|
||||||
});
|
|
||||||
|
|
||||||
headers.push({
|
|
||||||
source: normalizedSource,
|
|
||||||
headers: trackerRoute.headers,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const routesManifest = { ...originalManifest };
|
|
||||||
|
|
||||||
if (rewrites.length !== 0) {
|
|
||||||
const { buildCustomRoute } = require('next/dist/lib/build-custom-route');
|
|
||||||
|
|
||||||
const builtHeaders = headers.map(header => buildCustomRoute('header', header));
|
|
||||||
const builtRewrites = rewrites.map(rewrite => buildCustomRoute('rewrite', rewrite));
|
|
||||||
|
|
||||||
routesManifest.headers = [...originalManifest.headers, ...builtHeaders];
|
|
||||||
routesManifest.rewrites = [...builtRewrites, ...originalManifest.rewrites];
|
|
||||||
|
|
||||||
console.log('Using updated Next.js routes manifest');
|
|
||||||
} else {
|
|
||||||
console.log('Using original Next.js routes manifest');
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(routesManifestPath, JSON.stringify(routesManifest, null, 2));
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue