diff --git a/.gitignore b/.gitignore index 5ef6a52..a0c0d54 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ # production /build +.output/ # misc .DS_Store diff --git a/Dockerfile b/Dockerfile index 0142d39..80122cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,6 @@ FROM node:22-alpine AS base -ARG NEXT_PUBLIC_INSTAGRAM_ACCESS_TOKEN - -# Install dependencies only when needed +# Stage 1: Install dependencies FROM base AS deps # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. RUN apk add --no-cache libc6-compat @@ -18,54 +16,47 @@ RUN \ fi -# Rebuild the source code only when needed +# Stage 2: Rebuild the source code only when needed FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . -# Next.js collects completely anonymous telemetry data about general usage. -# Learn more here: https://nextjs.org/telemetry -# Uncomment the following line in case you want to disable telemetry during the build. -ENV NEXT_TELEMETRY_DISABLED=1 +# Environment variables needed during build time +ARG INSTAGRAM_ACCESS_TOKEN +ENV INSTAGRAM_ACCESS_TOKEN=$INSTAGRAM_ACCESS_TOKEN RUN \ - if [ -f yarn.lock ]; then yarn run build; \ + if [ -f yarn.lock ]; then yarn build; \ elif [ -f package-lock.json ]; then npm run build; \ elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ - else echo "Lockfile not found." && exit 1; \ + else npm run build; \ fi -# Production image, copy all the files and run next + +# Stage 3: Production image, copy all the files and run nitro FROM base AS runner WORKDIR /app ENV NODE_ENV=production -# Uncomment the following line in case you want to disable telemetry during runtime. -ENV NEXT_TELEMETRY_DISABLED=1 +# Set host to 0.0.0.0 to ensure it's accessible outside the container +ENV HOST=0.0.0.0 +ENV PORT=3000 RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs +RUN adduser --system --uid 1001 nitrojs -COPY --from=builder /app/public ./public +# Copy the build output from the builder stage +# TanStack Start/Nitro builds into the .output directory +COPY --from=builder --chown=nitrojs:nodejs /app/.output ./.output -# Set the correct permission for prerender cache -RUN mkdir .next -RUN chown nextjs:nodejs .next - -# Automatically leverage output traces to reduce image size -# 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/public ./public -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static - -USER nextjs +USER nitrojs EXPOSE 3000 -ENV PORT=3000 +# Health check to ensure the server is responding +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1 -# server.js is created by next build from the standalone output -# https://nextjs.org/docs/pages/api-reference/next-config-js/output -ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] \ No newline at end of file +# server.mjs is created by nitro build +CMD ["node", ".output/server/index.mjs"] \ No newline at end of file diff --git a/Makefile b/Makefile index 3b1c9a7..8747722 100644 --- a/Makefile +++ b/Makefile @@ -4,5 +4,26 @@ build-production: ## Build the production docker image. --platform linux/amd64,linux/arm64/v8 \ --tag registry.tanshu.com/mozimo:latest \ $(if $(TAG),--tag registry.tanshu.com/mozimo:$(TAG)) \ + --pull \ --push \ git@github.com:tanshu/mozimo.git + + +.PHONY: build-check +build-check: ## Multi-arch build without push (compile check) + @docker buildx build \ + --platform linux/amd64,linux/arm64/v8 \ + --tag mozimo:test \ + --pull \ + --progress=plain \ + git@git.tanshu.com:tanshu/mozimo.git + +.PHONY: build-check-local +build-check-local: ## Multi-arch build without push (compile check) + @git archive --format=tar HEAD | docker buildx build \ + --platform linux/amd64 \ + --tag barker:test \ + --pull \ + --progress=plain \ + --load \ + - diff --git a/ansible/vars/default.yml b/ansible/vars/default.yml index 02f9e42..089c5c4 100644 --- a/ansible/vars/default.yml +++ b/ansible/vars/default.yml @@ -16,7 +16,7 @@ docker_image: "{{ registry }}/{{ title }}:{{ tag }}" docker_container: "{{ title }}" docker_port: 3000 -instagram_token: IGQWRQSUY4b3RQWU9ZARHlVVUFDaWxJZAWFOUVllM0NxMk1zSHJ5X2JGc2dpRUxyTjBaeDNhUm0yaFZAQeUotVU9VUmFEQkJxU25CdFp3bURSZAGtnLXhCZAHVId21SWUNiNjVzc0pjZAlhPNDRxTDFzZAEQ0ZAXoyVlpUaHcZD +instagram_token: IGQWRhYzlibzE4VEpNYzZA2eHEtRkVLUXJiT3NyVU9mNjlNRzM1cmd2NzY0SGxtX1ZAVVGVwb1dkbFl4VlVWaW02aFhEakQzeUp3NjBCSktRR2lQYlgwV3UwMG1seTFsWDBMSzZAHejNYdlE5RFMzU0tqbS1OVEttN0UZD caddy_container: caddy diff --git a/eslint.config.mjs b/eslint.config.mjs index c85fb67..b2a1eb8 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,8 +9,6 @@ const compat = new FlatCompat({ baseDirectory: __dirname, }); -const eslintConfig = [ - ...compat.extends("next/core-web-vitals", "next/typescript"), -]; +const eslintConfig = [{}]; export default eslintConfig; diff --git a/src/app/__root.tsx b/src/app/__root.tsx index c497fec..d686505 100644 --- a/src/app/__root.tsx +++ b/src/app/__root.tsx @@ -1,6 +1,9 @@ import { createRootRoute, Outlet, HeadContent, Scripts } from '@tanstack/react-router'; +import { LazyMotion } from 'framer-motion'; import appCss from './globals.css?url'; +const loadFeatures = () => import('framer-motion').then(res => res.domAnimation); + export const Route = createRootRoute({ head: () => ({ meta: [ @@ -68,7 +71,9 @@ function RootLayout() { Since the Inter Google Font is loaded via the stylesheet above, it will automatically apply if configured in Tailwind CSS. */}
-