From 56515d4ed09d911b51b2a34decc590b2fcf0e920 Mon Sep 17 00:00:00 2001 From: eldyyuda Date: Fri, 4 Jul 2025 16:49:11 +0700 Subject: [PATCH] feat(docker):adding docker-compose and dockerfile --- Docker/dev.Dockerfile | 37 +++++++++++++++ Docker/prod.Dockerfile | 99 +++++++++++++++++++++++++++++++++++++++++ docker-compose.dev.yml | 30 +++++++++++++ docker-compose.prod.yml | 25 +++++++++++ next.config.js | 13 +++++- src/app/absensi/page.js | 24 ---------- src/app/login/page.js | 15 +++++-- 7 files changed, 214 insertions(+), 29 deletions(-) create mode 100644 Docker/dev.Dockerfile create mode 100644 Docker/prod.Dockerfile create mode 100644 docker-compose.dev.yml create mode 100644 docker-compose.prod.yml delete mode 100644 src/app/absensi/page.js diff --git a/Docker/dev.Dockerfile b/Docker/dev.Dockerfile new file mode 100644 index 0000000..ed8cb5a --- /dev/null +++ b/Docker/dev.Dockerfile @@ -0,0 +1,37 @@ +FROM node:18-alpine + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + +COPY src ./src +COPY public ./public +COPY styles ./styles +COPY next.config.js . +COPY tailwind.config.js . +COPY postcss.config.js . +COPY theme.config.js . +COPY jsconfig.json . +# COPY tsconfig.json . +# COPY middleware.ts . + +# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry +# Uncomment the following line to disable telemetry at run time +# ENV NEXT_TELEMETRY_DISABLED 1 + +# Note: Don't expose ports here, Compose will handle that for us + +# Start Next.js in development mode based on the preferred package manager +CMD \ + if [ -f yarn.lock ]; then yarn dev; \ + elif [ -f package-lock.json ]; then npm run dev; \ + elif [ -f pnpm-lock.yaml ]; then pnpm dev; \ + else yarn dev; \ + fi \ No newline at end of file diff --git a/Docker/prod.Dockerfile b/Docker/prod.Dockerfile new file mode 100644 index 0000000..5577dad --- /dev/null +++ b/Docker/prod.Dockerfile @@ -0,0 +1,99 @@ +FROM node:18-alpine AS base + +# Step 1. Rebuild the source code only when needed +FROM base AS builder + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +# Omit --production flag for TypeScript devDependencies +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ + # Allow install without lockfile, so example works even without Node.js installed locally + else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && yarn install; \ + fi + +COPY src ./src +COPY public ./public +COPY styles ./styles +COPY next.config.js . +COPY tailwind.config.js . +COPY postcss.config.js . +COPY theme.config.js . +COPY jsconfig.json . +# COPY tsconfig.json . +# COPY middleware.ts . + +# Environment variables must be present at build time +# https://github.com/vercel/next.js/discussions/14030 +ARG NEXTAUTH_URL +ENV NEXTAUTH_URL=${NEXTAUTH_URL} +ARG NEXTAUTH_PUBLIC_API_URL +ENV NEXTAUTH_PUBLIC_API_URL=${NEXTAUTH_PUBLIC_API_URL} +ARG NEXT_PUBLIC_API_GEOLOCATION_KEY +ENV NEXT_PUBLIC_API_GEOLOCATION_KEY=${NEXT_PUBLIC_API_GEOLOCATION_KEY} +ARG NODE_ENV=${NODE_ENV:-production} +ENV NODE_ENV=${NODE_ENV} +ARG NEXTAUTH_SECRET +ENV NEXTAUTH_SECRET=${NEXTAUTH_SECRET} + + + + +# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry +# Uncomment the following line to disable telemetry at build time +# ENV NEXT_TELEMETRY_DISABLED 1 + +# Build Next.js based on the preferred package manager +RUN \ + if [ -f yarn.lock ]; then yarn build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then pnpm build; \ + else yarn build; \ + fi + +# Note: It is not necessary to add an intermediate step that does a full copy of `node_modules` here + +# Step 2. Production image, copy all the files and run next +FROM base AS runner + +WORKDIR /app + +# Don't run production as root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +USER nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder /app/src ./src +COPY --from=builder /app/styles ./styles + +# 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/.next/static ./.next/static + +# Environment variables must be redefined at run time +ARG NEXTAUTH_URL +ENV NEXTAUTH_URL=${NEXTAUTH_URL} +ARG NEXT_PUBLIC_API_URL +ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} +ARG NEXT_PUBLIC_API_GEOLOCATION_KEY +ENV NEXT_PUBLIC_API_GEOLOCATION_KEY=${NEXT_PUBLIC_API_GEOLOCATION_KEY} +ARG NODE_ENV=${NODE_ENV:-production} +ENV NODE_ENV=${NODE_ENV} +ARG NEXTAUTH_SECRET +ENV NEXTAUTH_SECRET=${NEXTAUTH_SECRET} +ARG NODE_TLS_REJECT_UNAUTHORIZED +ENV NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-0} + + +# Uncomment the following line to disable telemetry at run time +# ENV NEXT_TELEMETRY_DISABLED 1 + +# Note: Don't expose ports here, Compose will handle that for us + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..b79f358 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,30 @@ +services: + next-app-dev: + container_name: absensi-frontend-dev + image: absensi-frontend-dev + build: + context: . + dockerfile: ./Docker/dev.Dockerfile + + # Set environment variables directly in the docker-compose file + environment: + NEXTAUTH_URL: ${NEXTAUTH_URL} + NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} + + # Set envrionment variables based on the .env file + env_file: + - .env + volumes: + - ./src:/app/src + - ./public:/app/public + - ./styles:/app/styles + + restart: always + ports: + - 3000:3000 + networks: + - absensi-network + +networks: + absensi-network: + driver: bridge diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..a13f758 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,25 @@ +services: + next-app: + container_name: absensi-frontend-prod + image: absensi-frontend-prod + build: + context: . + dockerfile: ./Docker/prod.Dockerfile + environment: + NEXTAUTH_URL: ${NEXTAUTH_URL} + NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} + NEXT_PUBLIC_API_GEOLOCATION_KEY: ${NEXT_PUBLIC_API_GEOLOCATION_KEY} + NODE_ENV: ${NODE_ENV} + NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} + NODE_TLS_REJECT_UNAUTHORIZED: ${NODE_TLS_REJECT_UNAUTHORIZED:-0} + env_file: + - .env.production + restart: always + ports: + - 3002:3000 + networks: + - absensi-network-prod + +networks: + absensi-network-prod: + driver: bridge diff --git a/next.config.js b/next.config.js index 680badd..b866ef0 100644 --- a/next.config.js +++ b/next.config.js @@ -1,12 +1,17 @@ +const webpack = require('webpack'); const withPWA = require('next-pwa')({ dest: 'public', register: true, skipWaiting: true, - disable: process.env.NODE_ENV === 'development', // opsional + // disable: process.env.NODE_ENV === 'development', // opsional }); /** @type {import('next').NextConfig} */ const nextConfig = { + output: "standalone", + eslint: { + ignoreDuringBuilds: true, + }, // konfigurasi lain jika ada async rewrites() { return [ @@ -16,6 +21,12 @@ const nextConfig = { }, ]; }, + webpack: (config) => { + config.plugins.push( + new webpack.ContextReplacementPlugin(/face-api/) + ); + return config; + }, }; module.exports = withPWA(nextConfig); diff --git a/src/app/absensi/page.js b/src/app/absensi/page.js deleted file mode 100644 index 4b1a2d5..0000000 --- a/src/app/absensi/page.js +++ /dev/null @@ -1,24 +0,0 @@ -"use client"; - -import { useState } from "react"; - -export default function AbsensiPage() { - const [waktu] = useState(new Date().toLocaleString()); - - const handleAbsen = () => { - alert("Absen berhasil pada " + waktu); - }; - - return ( -
-

Halaman Absensi

-

Waktu: {waktu}

- -
- ); -} diff --git a/src/app/login/page.js b/src/app/login/page.js index bd1af80..af319ce 100644 --- a/src/app/login/page.js +++ b/src/app/login/page.js @@ -1,12 +1,11 @@ 'use client' -import React, { useEffect, useState } from 'react'; +import React, { Suspense, useEffect, useState } from 'react'; import { Button, Form, Input } from 'antd'; import { signIn } from 'next-auth/react'; -import { useRouter, useSearchParams } from 'next/navigation'; +import { useRouter, useSearchParams } from 'next/navigation'; - -export default function Login() { +function LoginForm() { const router = useRouter(); const searchParams = useSearchParams(); const error = searchParams.get('error'); @@ -66,3 +65,11 @@ export default function Login() { ); } + +export default function Login() { + return ( + + + + ); +} \ No newline at end of file -- 2.26.2