diff --git a/Dockerfile b/Dockerfile index f877d14..26dfe16 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,50 +1,74 @@ -# Use smaller base image -FROM node:18-alpine AS base -# Install dependencies only when needed +# Base image for all stages +FROM node:20-alpine AS base + +### Dependencies Stage ### FROM base AS deps -RUN apk add --no-cache libc6-compat +# Set a fast and reliable Alpine mirror (mirrors.tuna.tsinghua.edu.cn is globally accessible) +# Check if 'git' is needed (only required if package.json has Git-based dependencies) +RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.22/main" > /etc/apk/repositories && \ + echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.22/community" >> /etc/apk/repositories && \ + apk update --verbose && \ + apk add --no-cache --verbose libc6-compat git + +# Setup pnpm environment +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable +RUN corepack prepare pnpm@latest --activate + WORKDIR /app -# Copy package files -COPY package.json pnpm-lock.yaml* ./ -RUN corepack enable pnpm && pnpm install --frozen-lockfile --production=false +# Install dependencies with pnpm +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prefer-frozen-lockfile -# Build the source code +### Builder Stage ### FROM base AS builder +# Enable pnpm +RUN corepack enable +RUN corepack prepare pnpm@latest --activate + WORKDIR /app + +# Copy node_modules from deps stage COPY --from=deps /app/node_modules ./node_modules +# Copy all source files COPY . . +# Build the Next.js application +RUN pnpm build -# Optimize build process -ENV NEXT_TELEMETRY_DISABLED=1 -ENV NODE_ENV=production - -# Build with optimizations -RUN corepack enable pnpm && \ - pnpm build && \ - pnpm prune --production - -# Production image +### Production Runner Stage ### FROM base AS runner -WORKDIR /app +# Set production environment +ENV NODE_ENV production -ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 +# Disable Next.js telemetry +# Learn more: https://nextjs.org/telemetry +ENV NEXT_TELEMETRY_DISABLED 1 -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs +# Create non-root user and set permissions +RUN addgroup nodejs +RUN adduser -SDH nextjs +RUN mkdir .next +RUN chown nextjs:nodejs .next -# Copy built application +# Copy built artifacts with correct ownership 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/public ./public +# Switch to non-root user USER nextjs +# Expose port for the application EXPOSE 3000 +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" -ENV PORT=3000 -ENV HOSTNAME="0.0.0.0" +# Healthcheck using curl (available in node:20-alpine, unlike wget) +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:3000/health || exit 1 -CMD ["node", "server.js"] \ No newline at end of file +# Start the Next.js application +CMD ["node", "server.js"] diff --git a/app/layout.tsx b/app/layout.tsx index 18e62a2..64e0e37 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,16 +1,16 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +// import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); +// const geistSans = Geist({ +// variable: "--font-geist-sans", +// subsets: ["latin"], +// }); -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); +// const geistMono = Geist_Mono({ +// variable: "--font-geist-mono", +// subsets: ["latin"], +// }); export const metadata: Metadata = { title: "Operify Tech - A Leader in Next Generation Sequencing (NGS) Technology", @@ -24,9 +24,10 @@ export default function RootLayout({ }>) { return ( - + > */} + {children} diff --git a/app/research/page.js b/app/research/page.js index 5709b61..9a0e264 100644 --- a/app/research/page.js +++ b/app/research/page.js @@ -1,7 +1,7 @@ import React from 'react'; import PageLayout from '../components/Layout/PageLayout'; -import ResearchHero from '../components/Research/ResearchHero' -import PlantResearch from '../components/Research/PlantResearch'; +import ResearchHero from '../components/research/ResearchHero' +import PlantResearch from '../components/research/PlantResearch'; import AnimalResearch from '../components/research/AnimalResearch'; import MicrobialResearch from '../components/research/MicrobialResearch'; import HumanResearch from '../components/research/HumanResearch';