forked from mapasculturais/mapasculturais
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathDockerfile
More file actions
275 lines (222 loc) · 9.7 KB
/
Dockerfile
File metadata and controls
275 lines (222 loc) · 9.7 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# syntax=docker/dockerfile:1
ARG NODE_VERSION=20
ARG PHP_VERSION=8.4
# =============================================================================
# Stage 1: Node.js builder - Compiles frontend assets
# =============================================================================
FROM node:${NODE_VERSION}-alpine AS builder-node
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /build
COPY src/ ./
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install
RUN pnpm run build
# Compile SASS for BaseV1 theme
RUN if [ -f themes/BaseV1/assets/css/sass/main.scss ]; then \
./node_scripts/node_modules/.bin/sass themes/BaseV1/assets/css/sass/main.scss:themes/BaseV1/assets/css/main.css --quiet; \
fi
# Resolve pnpm symlinks for vendor CSS files needed by the PHP AssetManager at runtime.
# These CSS files are served directly from node_modules (not bundled by webpack).
# The packages are deps of modules/Components, so their node_modules live there.
# -L dereferences symlinks so the real files are copied (pnpm uses symlinks to .pnpm store).
RUN mkdir -p /vendor-css/@vuepic/vue-datepicker/dist \
/vendor-css/floating-vue/dist \
/vendor-css/leaflet/dist \
/vendor-css/@vueform/slider/themes \
/vendor-css/leaflet.markercluster/dist \
/vendor-css/shepherd.js/dist/css && \
cp -L modules/Components/node_modules/@vuepic/vue-datepicker/dist/main.css /vendor-css/@vuepic/vue-datepicker/dist/main.css && \
cp -L modules/Components/node_modules/floating-vue/dist/style.css /vendor-css/floating-vue/dist/style.css && \
cp -L modules/Components/node_modules/leaflet/dist/leaflet.css /vendor-css/leaflet/dist/leaflet.css && \
cp -L modules/Components/node_modules/@vueform/slider/themes/default.css /vendor-css/@vueform/slider/themes/default.css && \
cp -L modules/Components/node_modules/leaflet.markercluster/dist/MarkerCluster.css /vendor-css/leaflet.markercluster/dist/MarkerCluster.css && \
cp -L modules/Components/node_modules/leaflet.markercluster/dist/MarkerCluster.Default.css /vendor-css/leaflet.markercluster/dist/MarkerCluster.Default.css && \
cp -L modules/Components/node_modules/shepherd.js/dist/css/shepherd.css /vendor-css/shepherd.js/dist/css/shepherd.css
# Cleanup development files from node_modules
RUN find . -path '*/node_modules/*' -type f \( \
-name '*.ts' -o -name '*.tsx' -o -name '*.map' -o \
-name '*.md' -o -name '*.markdown' -o \
-name 'LICENSE*' -o -name 'CHANGELOG*' -o -name 'README*' -o \
-name '*.d.ts' -o -name 'tsconfig*' \
\) -delete 2>/dev/null || true && \
find . -path '*/node_modules/*' -name '.git' -type d -exec rm -rf {} + 2>/dev/null || true
# =============================================================================
# Stage 2: Composer builder - Installs PHP dependencies
# =============================================================================
FROM php:${PHP_VERSION}-cli-alpine AS builder-composer
RUN apk add --no-cache git unzip
RUN apk add --no-cache \
libpng \
libjpeg-turbo \
freetype \
libzip && \
apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
libzip-dev && \
docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install -j$(nproc) gd zip && \
docker-php-ext-enable gd zip && \
apk del .build-deps && \
rm -rf /tmp/pear /var/cache/apk/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /build
COPY composer.json composer.lock ./
ARG COMPOSER_ARGS="--no-dev --optimize-autoloader --no-interaction"
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN composer install ${COMPOSER_ARGS} --no-scripts
# =============================================================================
# Stage 3: Production image - PHP-FPM + Nginx
# =============================================================================
FROM php:${PHP_VERSION}-fpm-alpine AS production
LABEL org.opencontainers.image.title="Mapas"
LABEL org.opencontainers.image.description="Platform for cultural mapping"
LABEL org.opencontainers.image.vendor="RedeMapas"
LABEL org.opencontainers.image.source="https://github.com/redemapas/mapas"
LABEL org.opencontainers.image.licenses="AGPL-3.0"
# Install runtime dependencies (including nginx)
RUN apk add --no-cache \
sudo \
bash \
git \
imagemagick \
libpq \
libzip \
libpng \
libjpeg-turbo \
freetype \
icu-libs \
zstd-libs \
curl \
nginx
# Install build dependencies for PHP extensions
RUN apk add --no-cache --virtual .build-deps \
$PHPIZE_DEPS \
imagemagick-dev \
postgresql-dev \
libzip-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
icu-dev \
linux-headers
# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install -j$(nproc) \
pdo_pgsql \
zip \
gd \
intl
# Install APCu
RUN pecl install apcu && \
docker-php-ext-enable apcu
# Install Imagick
RUN pecl install imagick && \
docker-php-ext-enable imagick
# Install Redis
# RUN pecl install redis && \
# docker-php-ext-enable redis
# Cleanup build dependencies
RUN apk del .build-deps && \
rm -rf /tmp/pear /var/cache/apk/*
# Create www-data user if not exists and setup directories
RUN mkdir -p /var/www/var/DoctrineProxies \
/var/www/var/logs \
/var/www/var/private-files \
/var/www/html/assets \
/var/www/html/files && \
chown -R www-data:www-data /var/www
WORKDIR /var/www
# Copy composer dependencies
COPY --from=builder-composer /build/vendor ./vendor/
# Copy application source
COPY --chown=www-data:www-data config ./config/
COPY --chown=www-data:www-data public ./html/
COPY --chown=www-data:www-data health.php /var/www/html/health.php
COPY --chown=www-data:www-data scripts ./scripts/
COPY --chown=www-data:www-data src ./src/
# Copy built frontend assets from Node.js stage
COPY --from=builder-node --chown=www-data:www-data /build/modules/ ./src/modules/
COPY --from=builder-node --chown=www-data:www-data /build/themes/ ./src/themes/
COPY --from=builder-node --chown=www-data:www-data /build/plugins/ ./src/plugins/
# The builder-node COPY above brings node_modules symlinks from the pnpm store.
# Docker cannot COPY real files over existing symlinks, so remove them first.
RUN rm -rf ./src/modules/Components/node_modules
# Copy vendor CSS files from node_modules that the PHP AssetManager serves at runtime.
# These are referenced via '../node_modules/...' relative to the Components module assets dir.
# /vendor-css was pre-populated in the builder stage with real files (pnpm symlinks resolved).
COPY --from=builder-node --chown=www-data:www-data /vendor-css/ ./src/modules/Components/node_modules/
# Copy version file
COPY version.txt ./version.txt
# Copy PHP configuration
COPY docker/production/php.ini /usr/local/etc/php/php.ini
COPY docker/timezone.ini /usr/local/etc/php/conf.d/timezone.ini
# Copy PHP-FPM pool configuration and modify for Unix socket
COPY docker/production/www.conf /usr/local/etc/php-fpm.d/www.conf
RUN sed -i 's/^listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm\/php-fpm.sock/' /usr/local/etc/php-fpm.d/www.conf && \
sed -i 's/^;listen.owner = www-data/listen.owner = www-data/' /usr/local/etc/php-fpm.d/www.conf && \
sed -i 's/^;listen.group = www-data/listen.group = www-data/' /usr/local/etc/php-fpm.d/www.conf && \
sed -i 's/^;listen.mode = 0660/listen.mode = 0660/' /usr/local/etc/php-fpm.d/www.conf
# Copy Nginx configuration for Unix socket
COPY docker/production/nginx.conf /etc/nginx/nginx.conf
# Create socket directory and set permissions
RUN mkdir -p /var/run/php-fpm && \
chown -R www-data:www-data /var/run/php-fpm
# Copy entrypoint and cron scripts
COPY docker/entrypoint.sh /entrypoint.sh
COPY docker/jobs-cron.sh /jobs-cron.sh
COPY docker/recreate-pending-pcache-cron.sh /recreate-pending-pcache-cron.sh
RUN chmod +x /entrypoint.sh /jobs-cron.sh /recreate-pending-pcache-cron.sh
# Create start script that starts PHP-FPM and Nginx
RUN cat > /start.sh << 'EOF'
#!/bin/sh
set -e
# Start PHP-FPM in background
php-fpm --daemonize
# Wait for socket to be created
max_wait=10
count=0
while [ ! -S /var/run/php-fpm/php-fpm.sock ] && [ $count -lt $max_wait ]; do
sleep 1
count=$((count+1))
done
# Start nginx in foreground
exec nginx -g "daemon off;"
EOF
RUN chmod +x /start.sh
# Create symlink for public
RUN ln -sf /var/www/html /var/www/public
# Ensure proper permissions
RUN chown -R www-data:www-data /var/www/html/ /var/www/var/
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/start.sh"]
# Health check using the health.php endpoint
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost/health.php || exit 1
# =============================================================================
# Stage 4: Development image - Includes build tools
# =============================================================================
FROM production AS development
# Install Node.js and pnpm for hot-reload development
RUN apk add --no-cache nodejs npm && \
npm install -g pnpm
# Install pcov for code coverage (lightweight, production-safe to disable)
RUN apk add --no-cache --virtual .pcov-deps $PHPIZE_DEPS linux-headers && \
pecl install pcov && \
docker-php-ext-enable pcov && \
apk del .pcov-deps && \
rm -rf /tmp/pear /var/cache/apk/*
# Install xdebug (but don't enable by default)
# RUN apk add --no-cache --virtual .xdebug-deps $PHPIZE_DEPS linux-headers && \
# pecl install xdebug && \
# apk del .xdebug-deps && \
# ln -s $(find /usr/local/lib/php/extensions/ -name xdebug.so) /usr/local/lib/php/extensions/xdebug.so
# Copy development files
COPY docker/development/router.php /var/www/dev/router.php
COPY docker/development/start.sh /var/www/dev/start.sh
RUN chmod +x /var/www/dev/start.sh
# Development uses built-in PHP server
EXPOSE 80
CMD ["/var/www/dev/start.sh"]