Full rewrite of the portfolio site from Next.js 14 to .NET 10: - ASP.NET Core 10 Razor Pages, no Node.js dependency - EF Core 10 + SQLite (same schema as before — data survives upgrade) - Cookie authentication (same single-password model) - Resend contact form via HttpClient - Bilingual FA/EN via locale cookie + BasePageModel - All UI ported to Razor Pages with Tailwind CDN + custom CSS - Vanilla JS: particles, typewriter, cursor, animations, portfolio modal - Dockerfile: SDK 10.0-alpine → aspnet 10.0-alpine (no npm/Node needed) - CI/CD: dropped NPM_TOKEN, ADMIN_SESSION_SECRET — pure dotnet publish Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+25
-51
@@ -1,64 +1,38 @@
|
||||
ARG NODE_IMAGE=mirror.soroushasadi.com/node:20-alpine
|
||||
ARG DOTNET_IMAGE=mcr.microsoft.com/dotnet/aspnet:10.0-alpine
|
||||
ARG SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:10.0-alpine
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 1. Builder — installs deps (including native better-sqlite3 compilation)
|
||||
# then produces the standalone Next.js server bundle.
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM ${NODE_IMAGE} AS builder
|
||||
WORKDIR /app
|
||||
# ── Build ─────────────────────────────────────────────────────────────────────
|
||||
FROM ${SDK_IMAGE} AS build
|
||||
WORKDIR /src
|
||||
|
||||
# libc6-compat: needed by Next.js SWC binaries on Alpine.
|
||||
# python3 / make / g++: needed to compile better-sqlite3 native addon.
|
||||
RUN apk add --no-cache libc6-compat python3 make g++ ca-certificates
|
||||
COPY SoroushAsadi.Web.csproj ./
|
||||
RUN dotnet restore --runtime linux-musl-x64
|
||||
|
||||
ARG NPM_TOKEN=""
|
||||
COPY package.json package-lock.json .npmrc ./
|
||||
RUN if [ -n "$NPM_TOKEN" ]; then \
|
||||
echo "//mirror.soroushasadi.com/repository/npm-group/:_authToken=${NPM_TOKEN}" >> .npmrc ; \
|
||||
fi \
|
||||
&& npm ci \
|
||||
&& echo "=== post-install check ===" \
|
||||
&& (test -d node_modules/next \
|
||||
&& echo "OK: node_modules/next found: $(cat node_modules/next/package.json | grep '\"version\"' | head -1)" \
|
||||
|| (echo "FATAL: node_modules/next is missing after npm ci" && exit 1))
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
COPY . .
|
||||
# Diagnose what's in .bin after install, then invoke next directly via node
|
||||
# to bypass any PATH / symlink resolution issues with `npm run`.
|
||||
RUN ls node_modules/.bin/next 2>&1 || echo "WARN: next not in .bin" ; \
|
||||
node node_modules/next/dist/bin/next build
|
||||
RUN dotnet publish SoroushAsadi.Web.csproj \
|
||||
--no-restore \
|
||||
--runtime linux-musl-x64 \
|
||||
--self-contained false \
|
||||
-c Release \
|
||||
-o /app/publish
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 2. Runner — minimal image. Standalone server + static assets only.
|
||||
# Content DB + uploads live in /data (mounted volume).
|
||||
# ---------------------------------------------------------------------------
|
||||
FROM ${NODE_IMAGE} AS runner
|
||||
# ── Runtime ───────────────────────────────────────────────────────────────────
|
||||
FROM ${DOTNET_IMAGE} AS runner
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache libc6-compat ca-certificates
|
||||
RUN apk add --no-cache ca-certificates \
|
||||
&& addgroup -g 1001 dotnet \
|
||||
&& adduser -u 1001 -G dotnet -h /home/dotnet -D dotnet
|
||||
|
||||
ENV NODE_ENV=production \
|
||||
NEXT_TELEMETRY_DISABLED=1 \
|
||||
PORT=3000 \
|
||||
HOSTNAME=0.0.0.0 \
|
||||
DATA_DIR=/data
|
||||
COPY --from=build /app/publish ./
|
||||
|
||||
RUN addgroup -g 1001 nodejs && adduser -u 1001 -G nodejs -h /home/nextjs -D nextjs
|
||||
ENV ASPNETCORE_ENVIRONMENT=Production \
|
||||
ASPNETCORE_URLS=http://+:3000 \
|
||||
DataDir=/data
|
||||
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Native addon compiled in builder on Alpine/musl — copy explicitly as a
|
||||
# safety net in case file tracing misses the .node binary.
|
||||
COPY --from=builder /app/node_modules/better-sqlite3 ./node_modules/better-sqlite3
|
||||
COPY --from=builder /app/node_modules/bindings ./node_modules/bindings
|
||||
COPY --from=builder /app/node_modules/file-uri-to-path ./node_modules/file-uri-to-path
|
||||
|
||||
RUN mkdir -p /data/uploads && chown -R nextjs:nodejs /data /app
|
||||
USER nextjs
|
||||
RUN mkdir -p /data/uploads && chown -R dotnet:dotnet /data /app
|
||||
USER dotnet
|
||||
|
||||
VOLUME ["/data"]
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
ENTRYPOINT ["dotnet", "SoroushAsadi.Web.dll"]
|
||||
|
||||
Reference in New Issue
Block a user