feat: dockerfile
This commit is contained in:
16
.dockerignore
Normal file
16
.dockerignore
Normal file
@@ -0,0 +1,16 @@
|
||||
.env
|
||||
|
||||
Dockerfile
|
||||
./**/*/Dockerfile
|
||||
|
||||
.dockerignore
|
||||
|
||||
node_modules
|
||||
./**/*/node_modules
|
||||
|
||||
pnpm-debug.log
|
||||
./**/*/pnpm-debug.log
|
||||
|
||||
README.md
|
||||
.next
|
||||
.git
|
||||
85
apps/web/Dockerfile
Normal file
85
apps/web/Dockerfile
Normal file
@@ -0,0 +1,85 @@
|
||||
ARG NODE_VERSION=20
|
||||
ARG APP_DIRNAME=web
|
||||
ARG PROJECT=@kan/web
|
||||
|
||||
# 1. Alpine image
|
||||
FROM node:${NODE_VERSION}-alpine AS alpine
|
||||
RUN apk update
|
||||
RUN apk add --no-cache libc6-compat python3 make g++
|
||||
|
||||
# Setup pnpm and turbo on the alpine base
|
||||
FROM alpine AS base
|
||||
RUN corepack enable
|
||||
# Replace <your-major-version> with the major version installed in your repository. For example:
|
||||
# RUN npm install turbo@2.1.3 --global
|
||||
RUN npm install turbo@2.3.1 --global
|
||||
|
||||
RUN pnpm config set store-dir ~/.pnpm-store
|
||||
|
||||
# 2. Prune projects
|
||||
FROM base AS pruner
|
||||
# https://stackoverflow.com/questions/49681984/how-to-get-version-value-of-package-json-inside-of-dockerfile
|
||||
# RUN export VERSION=$(npm run version)
|
||||
|
||||
ARG PROJECT
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# It might be the path to <ROOT> turborepo
|
||||
COPY . .
|
||||
|
||||
# Generate a partial monorepo with a pruned lockfile for a target workspace.
|
||||
# Assuming "@acme/nextjs" is the name entered in the project's package.json: { name: "@acme/nextjs" }
|
||||
RUN turbo prune --scope=${PROJECT} --docker
|
||||
|
||||
# 3. Build the project
|
||||
FROM base AS builder
|
||||
ARG PROJECT
|
||||
|
||||
# Environment to skip .env validation on build
|
||||
ENV CI=true
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ARG NEXT_PUBLIC_KAN_ENV=${NEXT_PUBLIC_KAN_ENV}
|
||||
ARG NEXT_PUBLIC_UMAMI_ID=${NEXT_PUBLIC_UMAMI_ID}
|
||||
ARG NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
|
||||
ARG NEXT_PUBLIC_STORAGE_URL=${NEXT_PUBLIC_STORAGE_URL}
|
||||
ARG NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||
|
||||
# Copy lockfile and package.json's of isolated subworkspace
|
||||
COPY --from=pruner /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
COPY --from=pruner /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
|
||||
COPY --from=pruner /app/out/json/ .
|
||||
|
||||
# First install the dependencies (as they change less often)
|
||||
RUN --mount=type=cache,id=pnpm,target=~/.pnpm-store pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source code of isolated subworkspace
|
||||
COPY --from=pruner /app/out/full/ .
|
||||
|
||||
RUN pnpm build --filter=${PROJECT}
|
||||
|
||||
# 4. Final image - runner stage to run the application
|
||||
FROM base AS runner
|
||||
ARG APP_DIRNAME
|
||||
|
||||
# Don't run production as root
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
USER nextjs
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
COPY --chown=nextjs:nodejs --from=builder /app/ ./
|
||||
WORKDIR /app/apps/${APP_DIRNAME}
|
||||
|
||||
ARG PORT=3000
|
||||
ENV PORT=${PORT}
|
||||
EXPOSE ${PORT}
|
||||
|
||||
CMD ["pnpm", "start"]
|
||||
|
||||
41
docker-compose.yml
Normal file
41
docker-compose.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
web:
|
||||
ports:
|
||||
- "3000:3000"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./apps/web/Dockerfile
|
||||
args:
|
||||
NEXT_PUBLIC_KAN_ENV: ${NEXT_PUBLIC_KAN_ENV}
|
||||
NEXT_PUBLIC_UMAMI_ID: ${NEXT_PUBLIC_UMAMI_ID}
|
||||
NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL}
|
||||
NEXT_PUBLIC_STORAGE_URL: ${NEXT_PUBLIC_STORAGE_URL}
|
||||
NEXT_PUBLIC_AVATAR_BUCKET_NAME: ${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||
env_file:
|
||||
- .env
|
||||
command: ["pnpm", "start"]
|
||||
environment:
|
||||
- WEBSITE_URL=${WEBSITE_URL}
|
||||
- EMAIL_FROM=${EMAIL_FROM}
|
||||
- EMAIL_URL=${EMAIL_URL}
|
||||
- EMAIL_TOKEN=${EMAIL_TOKEN}
|
||||
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
|
||||
- BETTER_AUTH_URL=${BETTER_AUTH_URL}
|
||||
- BETTER_AUTH_TRUSTED_ORIGINS=${BETTER_AUTH_TRUSTED_ORIGINS}
|
||||
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
|
||||
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
||||
- POSTGRES_URL=${POSTGRES_URL}
|
||||
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
|
||||
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
|
||||
- S3_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID}
|
||||
- S3_SECRET_ACCESS_KEY=${S3_SECRET_ACCESS_KEY}
|
||||
- S3_REGION=${S3_REGION}
|
||||
- S3_ENDPOINT=${S3_ENDPOINT}
|
||||
- NEXT_PUBLIC_KAN_ENV=${NEXT_PUBLIC_KAN_ENV}
|
||||
- NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
|
||||
- NEXT_PUBLIC_STORAGE_URL=${NEXT_PUBLIC_STORAGE_URL}
|
||||
- NEXT_PUBLIC_AVATAR_BUCKET_NAME=${NEXT_PUBLIC_AVATAR_BUCKET_NAME}
|
||||
- NEXT_PUBLIC_STORAGE_DOMAIN=${NEXT_PUBLIC_STORAGE_DOMAIN}
|
||||
- NEXT_PUBLIC_UMAMI_ID=${NEXT_PUBLIC_UMAMI_ID}
|
||||
Reference in New Issue
Block a user