fix: Dockerfile workspace deps, PM2 log paths, jwt types, deploy script paths
This commit is contained in:
+23
-33
@@ -1,64 +1,54 @@
|
|||||||
# ═══════════════════════════════════════════════
|
# ═══════════════════════════════════════════════
|
||||||
# Harat's Booking — Production Dockerfile
|
# Harat's Booking — Production Dockerfile
|
||||||
# ═══════════════════════════════════════════════
|
# ═══════════════════════════════════════════════
|
||||||
# Client is pre-built by deploy.ps1 (npm run build)
|
|
||||||
# This Dockerfile only handles server + copies dist
|
|
||||||
# ═══════════════════════════════════════════════
|
|
||||||
|
|
||||||
# ── Stage 1: Server Dependencies ──
|
# ── Stage 1: Install production dependencies ──
|
||||||
FROM node:20-alpine AS server-deps
|
FROM node:20-alpine AS deps
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY server/package.json server/package-lock.json* ./
|
COPY package.json package-lock.json ./
|
||||||
RUN npm install --omit=dev
|
COPY server/package.json ./server/package.json
|
||||||
|
COPY packages/shared/package.json ./packages/shared/package.json
|
||||||
|
COPY packages/shared/ ./packages/shared/
|
||||||
|
|
||||||
# ── Stage 2: Prisma Generate ──
|
RUN npm install --omit=dev --workspace=server --workspace=packages/shared
|
||||||
FROM node:20-alpine AS prisma-gen
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY --from=server-deps /app/node_modules ./node_modules
|
COPY server/prisma ./server/prisma
|
||||||
COPY server/prisma ./prisma
|
RUN cd server && npx -y prisma generate
|
||||||
COPY server/package.json ./
|
|
||||||
|
|
||||||
RUN npx prisma generate
|
# ── Stage 2: Final Image ──
|
||||||
|
|
||||||
# ── Stage 3: Final Image ──
|
|
||||||
FROM node:20-alpine
|
FROM node:20-alpine
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Runtime deps + pm2
|
# Create user + dirs FIRST
|
||||||
|
RUN addgroup -S harats && adduser -S harats -G harats \
|
||||||
|
&& mkdir -p /data/logs \
|
||||||
|
&& chown -R harats:harats /data /app
|
||||||
|
|
||||||
|
# Runtime deps + pm2 (install as root, then fix ownership)
|
||||||
RUN apk add --no-cache curl \
|
RUN apk add --no-cache curl \
|
||||||
&& npm install -g pm2@latest \
|
&& npm install -g pm2@latest \
|
||||||
&& pm2 install pm2-logrotate \
|
&& pm2 install pm2-logrotate \
|
||||||
&& pm2 set pm2-logrotate:max_size 10M \
|
&& pm2 set pm2-logrotate:max_size 10M \
|
||||||
&& pm2 set pm2-logrotate:retain 7 \
|
&& pm2 set pm2-logrotate:retain 7 \
|
||||||
&& pm2 set pm2-logrotate:compress true
|
&& pm2 set pm2-logrotate:compress true \
|
||||||
|
&& pm2 kill
|
||||||
|
|
||||||
# Don't run as root
|
# Copy node_modules
|
||||||
RUN addgroup -S harats && adduser -S harats -G harats \
|
COPY --chown=harats:harats --from=deps /app/node_modules ./node_modules
|
||||||
&& mkdir -p /data/logs \
|
|
||||||
&& chown -R harats:harats /data
|
|
||||||
|
|
||||||
# Copy production node_modules (with generated Prisma client)
|
# Copy server compiled source (tsc outputs to dist/src/)
|
||||||
COPY --chown=harats:harats --from=prisma-gen /app/node_modules ./node_modules
|
|
||||||
|
|
||||||
# Copy server compiled source
|
|
||||||
COPY --chown=harats:harats server/dist ./dist
|
COPY --chown=harats:harats server/dist ./dist
|
||||||
COPY --chown=harats:harats server/prisma ./prisma
|
COPY --chown=harats:harats server/prisma ./prisma
|
||||||
|
|
||||||
# Copy shared package (workspace dependency)
|
|
||||||
COPY --chown=harats:harats packages/shared/ ./node_modules/@harats/shared/
|
|
||||||
|
|
||||||
# Copy pre-built client dist
|
# Copy pre-built client dist
|
||||||
COPY --chown=harats:harats client/dist ./public
|
COPY --chown=harats:harats client/dist ./public
|
||||||
|
|
||||||
# Copy ecosystem config
|
# Copy ecosystem config + version
|
||||||
COPY --chown=harats:harats ecosystem.config.cjs ./ecosystem.config.cjs
|
COPY --chown=harats:harats ecosystem.config.cjs ./ecosystem.config.cjs
|
||||||
|
|
||||||
# Copy version.json
|
|
||||||
COPY --chown=harats:harats version.json ./version.json
|
COPY --chown=harats:harats version.json ./version.json
|
||||||
|
|
||||||
# Version info (injected at build time)
|
# Version info
|
||||||
ARG BUILD_VERSION=0.0.0
|
ARG BUILD_VERSION=0.0.0
|
||||||
ARG BUILD_DATE=unknown
|
ARG BUILD_DATE=unknown
|
||||||
RUN echo "{\"version\":\"${BUILD_VERSION}\",\"build\":\"$(echo $BUILD_DATE | cut -c1-16)\",\"buildDate\":\"${BUILD_DATE}\"}" > version.json
|
RUN echo "{\"version\":\"${BUILD_VERSION}\",\"build\":\"$(echo $BUILD_DATE | cut -c1-16)\",\"buildDate\":\"${BUILD_DATE}\"}" > version.json
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export BUILD_VERSION="$DOCKER_TAG"
|
|||||||
export BUILD_DATE="$(date -Iseconds)"
|
export BUILD_DATE="$(date -Iseconds)"
|
||||||
|
|
||||||
echo " → harats-server:$DOCKER_TAG"
|
echo " → harats-server:$DOCKER_TAG"
|
||||||
docker compose -f "$DEPLOY_DIR/$COMPOSE_FILE" build \
|
docker compose -f "$DEPLOY_DIR/$COMPOSE_FILE" build --no-cache \
|
||||||
--build-arg BUILD_VERSION="$TAG" \
|
--build-arg BUILD_VERSION="$TAG" \
|
||||||
--build-arg BUILD_DATE="$BUILD_DATE" \
|
--build-arg BUILD_DATE="$BUILD_DATE" \
|
||||||
server
|
server
|
||||||
|
|||||||
+2
-1
@@ -177,9 +177,10 @@ try {
|
|||||||
server/dist/ `
|
server/dist/ `
|
||||||
server/prisma/ `
|
server/prisma/ `
|
||||||
server/package.json `
|
server/package.json `
|
||||||
server/package-lock.json `
|
|
||||||
client/dist/ `
|
client/dist/ `
|
||||||
packages/shared/ `
|
packages/shared/ `
|
||||||
|
package.json `
|
||||||
|
package-lock.json `
|
||||||
Dockerfile `
|
Dockerfile `
|
||||||
.dockerignore `
|
.dockerignore `
|
||||||
docker-compose.prod.yml `
|
docker-compose.prod.yml `
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ module.exports = {
|
|||||||
{
|
{
|
||||||
name: 'harats-server',
|
name: 'harats-server',
|
||||||
cwd: __dirname,
|
cwd: __dirname,
|
||||||
script: 'dist/index.js',
|
script: 'dist/src/index.js',
|
||||||
|
|
||||||
instances: 1,
|
instances: 1,
|
||||||
exec_mode: 'fork',
|
exec_mode: 'fork',
|
||||||
@@ -22,9 +22,9 @@ module.exports = {
|
|||||||
restart_delay: 2000,
|
restart_delay: 2000,
|
||||||
max_memory_restart: '512M',
|
max_memory_restart: '512M',
|
||||||
|
|
||||||
// Logs
|
// Logs (stdout/stderr for Docker)
|
||||||
error_file: '/data/logs/pm2-error.log',
|
error_file: '/dev/stderr',
|
||||||
out_file: '/data/logs/pm2-out.log',
|
out_file: '/dev/stdout',
|
||||||
merge_logs: true,
|
merge_logs: true,
|
||||||
time: true,
|
time: true,
|
||||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ interface TokenPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function generateAccessToken(payload: TokenPayload): string {
|
export function generateAccessToken(payload: TokenPayload): string {
|
||||||
return jwt.sign(payload, env.JWT_SECRET, { expiresIn: env.JWT_EXPIRES_IN });
|
return jwt.sign(payload, env.JWT_SECRET, { expiresIn: env.JWT_EXPIRES_IN as jwt.SignOptions['expiresIn'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRefreshToken(payload: TokenPayload): string {
|
export function generateRefreshToken(payload: TokenPayload): string {
|
||||||
return jwt.sign(payload, env.JWT_REFRESH_SECRET, { expiresIn: env.JWT_REFRESH_EXPIRES_IN });
|
return jwt.sign(payload, env.JWT_REFRESH_SECRET, { expiresIn: env.JWT_REFRESH_EXPIRES_IN as jwt.SignOptions['expiresIn'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyAccessToken(token: string): TokenPayload {
|
export function verifyAccessToken(token: string): TokenPayload {
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"build": "",
|
"build": "20260608-1539",
|
||||||
"buildDate": ""
|
"buildDate": "2026-06-08T15:39:12.1722623+07:00"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user