forked from kikootwo/ReadMeABook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdockerfile.unified
More file actions
144 lines (116 loc) · 4.9 KB
/
dockerfile.unified
File metadata and controls
144 lines (116 loc) · 4.9 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
# ReadMeABook - Unified Dockerfile
# Single container with PostgreSQL, Redis, and Next.js app
# Designed for easy deployment with minimal configuration
# Start from debian base with node preinstalled
FROM node:20-bookworm AS base
# Re-declare build arguments after FROM (ARGs before FROM are not available after)
ARG APP_VERSION=unknown
ARG GIT_COMMIT=unknown
ARG BUILD_DATE=unknown
# Install PostgreSQL 16 repository key
RUN apt-get update && apt-get install -y curl gnupg && \
install -d /etc/apt/keyrings && \
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/postgresql.list
# Install PostgreSQL, Redis, supervisord, and gosu (for reliable user switching)
RUN apt-get update && apt-get install -y \
postgresql-16 \
postgresql-client-16 \
redis-server \
supervisor \
curl \
openssl \
locales \
gosu \
xz-utils \
&& sed -i 's/^# \(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen \
&& locale-gen en_US.UTF-8 \
&& update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \
&& rm -rf /var/lib/apt/lists/*
# Install static ffmpeg (no transitive dependencies like imagemagick)
ADD https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz /tmp/ffmpeg.tar.xz
RUN cd /tmp && tar xf ffmpeg.tar.xz && \
cp ffmpeg-*-static/ffmpeg ffmpeg-*-static/ffprobe /usr/local/bin/ && \
rm -rf /tmp/ffmpeg*
# Remove imagemagick (pre-installed in node:20-bookworm base image, not needed)
RUN apt-get purge -y imagemagick imagemagick-6-common 'imagemagick-6*' \
'libmagickcore*' 'libmagickwand*' && \
apt-get autoremove -y --purge && \
rm -rf /var/lib/apt/lists/*
ENV LANG=en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
WORKDIR /app
# Copy package files
COPY package.json package-lock.json* ./
COPY prisma ./prisma/
# Install ALL dependencies (including dev dependencies needed for build)
RUN npm ci && npm cache clean --force
# Copy application code (before generating Prisma to avoid overwriting)
COPY . .
# Generate Prisma client AFTER copying code (prevents stale generated files from overwriting)
ENV DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy?schema=public"
RUN npx prisma generate
# Set version environment variables for build and runtime
ENV NEXT_PUBLIC_APP_VERSION=${APP_VERSION}
ENV NEXT_PUBLIC_GIT_COMMIT=${GIT_COMMIT}
ENV NEXT_PUBLIC_BUILD_DATE=${BUILD_DATE}
ENV APP_VERSION=${APP_VERSION}
ENV GIT_COMMIT=${GIT_COMMIT}
ENV BUILD_DATE=${BUILD_DATE}
# Build Next.js application
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
ENV TURBOPACK=0
RUN npm run build
# Reorganize for standalone output
# Next.js standalone mode creates .next/standalone/ with server.js
# We need to move files to root for supervisord to find server.js
RUN cp -r .next/standalone/* . && \
cp -r .next/static ./.next/static && \
cp -r public ./public 2>/dev/null || true
# Remove dev dependencies to reduce image size
RUN npm prune --production
# Create necessary directories
RUN mkdir -p \
/var/run/postgresql \
/var/lib/postgresql/data \
/var/lib/redis \
/app/config \
/app/cache \
/downloads \
/media \
/app/.next/cache \
/var/log/supervisor
# Setup PostgreSQL
RUN chown -R postgres:postgres /var/lib/postgresql /var/run/postgresql && \
chmod 2777 /var/run/postgresql
# Setup Redis data directory
RUN chown -R redis:redis /var/lib/redis
# Setup app directories (node user)
RUN chown -R node:node /app/config /app/cache /downloads /media /app/.next/cache
# Copy supervisord configuration
COPY --chown=root:root docker/unified/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy entrypoint script
COPY --chown=root:root docker/unified/entrypoint.sh /entrypoint.sh
# Convert line endings (Windows CRLF -> Unix LF) and make executable
RUN sed -i 's/\r$//' /entrypoint.sh && chmod +x /entrypoint.sh
# Copy app startup wrapper
COPY --chown=root:root docker/unified/app-start.sh /app/app-start.sh
# Convert line endings and make executable
RUN sed -i 's/\r$//' /app/app-start.sh && chmod +x /app/app-start.sh
# Copy redis startup wrapper
COPY --chown=root:root docker/unified/redis-start.sh /app/redis-start.sh
# Convert line endings and make executable
RUN sed -i 's/\r$//' /app/redis-start.sh && chmod +x /app/redis-start.sh
# Copy postgres startup wrapper
COPY --chown=root:root docker/unified/postgres-start.sh /app/postgres-start.sh
# Convert line endings and make executable
RUN sed -i 's/\r$//' /app/postgres-start.sh && chmod +x /app/postgres-start.sh
# Expose app port
EXPOSE 3030
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:3030/api/health || exit 1
# Set entrypoint
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]