Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,40 +1,50 @@
# ---- base stage ----
FROM node:22-alpine AS base

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN corepack enable && corepack prepare pnpm@10.10.0 --activate

# ---- deps stage ----
FROM base AS deps
# ---- build stage ----
FROM base AS builder

ENV NODE_ENV=production
ENV NEXT_PUBLIC_LINUX_DO_CREDIT_BACKEND_URL=https://build-placeholder.invalid
ENV LINUX_DO_CREDIT_SESSION_COOKIE_NAME=__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__
ENV LINUX_DO_CREDIT_RATE_LIMIT_ENABLED=__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__

WORKDIR /app

COPY package.json pnpm-lock.yaml ./

RUN pnpm install --frozen-lockfile

# ---- runner stage ----
FROM base AS runner
COPY . .

WORKDIR /app
RUN pnpm build

ENV NODE_ENV=production
RUN grep -rl \
-e "https://build-placeholder.invalid" \
-e "__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__" \
-e "__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__" \
/app/.next > /app/.replace.files

# accepts version argument to override package.json version
ARG VERSION=""
# ---- runner stage ----
FROM base AS runner

# accepts build date argument to set package.json build metadata
ARG VERSION=""
ARG BUILD_DATE=""

COPY --from=deps /app/node_modules ./node_modules
COPY . .
WORKDIR /app

COPY --from=builder /app .

# update package.json build metadata when build args are provided
RUN if [ -n "$VERSION" ] || [ -n "$BUILD_DATE" ]; then \
VERSION="$VERSION" BUILD_DATE="$BUILD_DATE" node -e "const fs = require('fs'); const pkg = require('./package.json'); const version = process.env.VERSION; const buildDate = process.env.BUILD_DATE; if (version) pkg.version = version; if (buildDate) pkg.buildDate = buildDate; fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\\n')"; \
fi

EXPOSE 3000

CMD ["sh", "-c", "pnpm build && pnpm start"]
ENTRYPOINT ["./entrypoint.sh"]
CMD ["pnpm", "start"]
38 changes: 38 additions & 0 deletions frontend/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/sh

set -e

replace_placeholder() {
local placeholder="$1"
local real_value="$2"

if [ -z "$real_value" ]; then
echo "⚠️ WARNING: Environment variable for placeholder '${placeholder}' is not set. Skipping replacement."
return 0
fi

echo "🔍 Replacing placeholder '${placeholder}' with value '${real_value}'"

local escaped
escaped=$(printf '%s\n' "$real_value" | sed 's/[&/\]/\\&/g')

local files
if [ -f /app/.replace.files ]; then
files=$(grep -l "$placeholder" $(cat /app/.replace.files) 2>/dev/null || true)
fi

if [ -z "$files" ]; then
echo "⚠️ WARNING: placeholder '${placeholder}' not found in any file"
else
local count
count=$(echo "$files" | wc -l)
echo "$files" | xargs sed -i "s|${placeholder}|${escaped}|g"
echo "✅ Replaced '${placeholder}' in ${count} file(s)"
fi
}

replace_placeholder "https://build-placeholder.invalid" "$NEXT_PUBLIC_LINUX_DO_CREDIT_BACKEND_URL"
replace_placeholder "__LINUX_DO_CREDIT_SESSION_COOKIE_NAME__" "$LINUX_DO_CREDIT_SESSION_COOKIE_NAME"
replace_placeholder "__LINUX_DO_CREDIT_RATE_LIMIT_ENABLED__" "$LINUX_DO_CREDIT_RATE_LIMIT_ENABLED"

exec "$@"
2 changes: 1 addition & 1 deletion frontend/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const nextConfig: NextConfig = {
experimental: {
},
async rewrites() {
const backendUrl = process.env.LINUX_DO_CREDIT_BACKEND_URL || 'http://localhost:8000';
const backendUrl = process.env.NEXT_PUBLIC_LINUX_DO_CREDIT_BACKEND_URL || 'http://localhost:8000';
return [
// 易支付兼容接口 - 创建订单
{
Expand Down
2 changes: 1 addition & 1 deletion frontend/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function proxy(request: NextRequest) {

/* API 请求:速率限制后放行 */
if (pathname.startsWith('/api/')) {
const rateLimitEnabled = !!process.env.LINUX_DO_CREDIT_RATE_LIMIT_ENABLED
const rateLimitEnabled = process.env.LINUX_DO_CREDIT_RATE_LIMIT_ENABLED === 'true'

if (rateLimitEnabled && shouldRateLimit(pathname)) {
const identifier = sessionCookie?.value ||
Expand Down
Loading