forked from dotnetfactory/personal-financial-dashboard
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
146 lines (116 loc) · 4.73 KB
/
Dockerfile
File metadata and controls
146 lines (116 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Multi-stage build for production
FROM node:20-alpine AS base
# Install dependencies only when needed
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
WORKDIR /app
# Add build arguments for cache invalidation
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
# Install ALL dependencies (including dev dependencies) for build
COPY package.json package-lock.json* ./
RUN npm ci --legacy-peer-deps
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
# Add build arguments for cache invalidation
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
ARG CACHE_BUST
# Copy dependencies from deps stage
COPY --from=deps /app/node_modules ./node_modules
# Copy source code with cache busting
COPY . .
# Generate Prisma client
RUN npx prisma generate
# Build the application with cache busting
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
# Add build arguments for cache invalidation
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
# Install necessary packages
RUN apk add --no-cache \
curl \
bash \
tzdata \
sqlite \
dcron
# Set timezone
ENV TZ=UTC
ENV NODE_ENV=production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Create necessary directories with proper ownership
RUN mkdir -p /app/data /app/logs /app/backups && \
chown -R nextjs:nodejs /app/data /app/logs /app/backups
# Copy the public folder
COPY --from=builder /app/public ./public
# 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/.next/static ./.next/static
# Copy Prisma files
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
# Copy scripts and compile TypeScript
COPY --from=builder /app/scripts ./scripts
RUN chmod +x scripts/init-db.sh && \
chmod +x scripts/start-with-backup-cron.sh && \
chown nextjs:nodejs scripts/init-db.sh scripts/start-with-backup-cron.sh
# Copy src/lib directory for backup functionality
COPY --from=builder /app/src/lib ./src/lib
RUN chown -R nextjs:nodejs src/lib
# Create enhanced startup script with validation and error handling
RUN echo '#!/bin/bash' > /app/start.sh && \
echo 'set -e' >> /app/start.sh && \
echo 'echo "=========================================="' >> /app/start.sh && \
echo 'echo "Personal Finance Dashboard - Starting Up"' >> /app/start.sh && \
echo 'echo "=========================================="' >> /app/start.sh && \
echo 'echo "Build Date: ${BUILD_DATE:-unknown}"' >> /app/start.sh && \
echo 'echo "Version: ${VERSION:-unknown}"' >> /app/start.sh && \
echo 'echo "Git Commit: ${VCS_REF:-unknown}"' >> /app/start.sh && \
echo 'echo ""' >> /app/start.sh && \
echo 'cd /app' >> /app/start.sh && \
echo 'export DATABASE_URL="file:/app/data/dev.db"' >> /app/start.sh && \
echo '' >> /app/start.sh && \
echo 'echo "Step 1: Initializing database..."' >> /app/start.sh && \
echo './scripts/init-db.sh' >> /app/start.sh && \
echo '' >> /app/start.sh && \
echo 'echo "Step 2: Starting Next.js application..."' >> /app/start.sh && \
echo 'echo "Application will be available at http://localhost:3000"' >> /app/start.sh && \
echo 'echo "Health check available at http://localhost:3000/api/health"' >> /app/start.sh && \
echo 'echo ""' >> /app/start.sh && \
echo 'echo "=========================================="' >> /app/start.sh && \
echo 'echo "Startup complete - Application is ready!"' >> /app/start.sh && \
echo 'echo "=========================================="' >> /app/start.sh && \
echo 'echo ""' >> /app/start.sh && \
echo 'exec node server.js' >> /app/start.sh && \
chmod +x /app/start.sh && \
chown nextjs:nodejs /app/start.sh
# Set ownership of app directories
RUN chown -R nextjs:nodejs /app
EXPOSE 3000
ENV PORT=3000
# set hostname to localhost
ENV HOSTNAME=0.0.0.0
# Enhanced health check with startup grace period
HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=5 \
CMD curl -f http://localhost:3000/api/health || exit 1
# Switch to nextjs user for security
USER nextjs
# Set entrypoint to the new cron+app startup script
ENTRYPOINT ["/app/scripts/start-with-backup-cron.sh"]
# Comment out the old start.sh CMD
# CMD ["/app/start.sh"]