Repository navigation
Expand file tree
/
Copy pathDockerfile.web
More file actions
130 lines (101 loc) · 4.58 KB
/
Copy pathDockerfile.web
File metadata and controls
130 lines (101 loc) · 4.58 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
# syntax=docker/dockerfile:1.28.0@sha256:bb22d9815c728170f72750f4e5b0d672e06176142e1d602c7e66c050100b7e5b
# ====== Stage 1: Base ======
FROM php:8.5.12-apache-trixie AS base
ARG DEBIAN_FRONTEND=noninteractive
# Install build dependencies (update+install together for caching)
RUN apt-get update && \
apt-get upgrade -y --no-install-recommends && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
libonig-dev \
libxml2-dev \
libxslt-dev \
libzip-dev \
mariadb-client
# Clean apt cache
RUN rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install -j"$(nproc)" \
mbstring \
mysqli \
pdo_mysql \
xsl \
zip
# Configure Apache
ENV APACHE_DOCUMENT_ROOT=/var/www/html
RUN sed -ri "s!/var/www/html!${APACHE_DOCUMENT_ROOT}!g" /etc/apache2/sites-available/000-default.conf
RUN a2enmod rewrite deflate headers expires
# Define Apache listen port (default 80), can be overridden in docker-compose
ENV APACHE_PORT=80
WORKDIR /var/www/html
# Use single quotes to make apache identify on runtime
RUN sed -i 's/Listen 80/Listen ${APACHE_PORT}/' /etc/apache2/ports.conf
COPY docker/apache-gzip.conf /etc/apache2/conf-available/gzip.conf
RUN a2enconf gzip
# ====== Stage 2: Dev ======
FROM base AS dev
# Install Node.js prerequisites (update+install together)
RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates curl gnupg
# Setup NodeSource repository (all in one RUN for atomicity)
RUN mkdir -p /etc/apt/keyrings && \
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_24.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
# Install Node.js (update+install together)
RUN apt-get update && \
apt-get install -y --no-install-recommends nodejs
# Clean up
RUN rm -rf /var/lib/apt/lists/*
# Install Composer
COPY --from=composer:2.10.3@sha256:af98f42dfff7c68ba8d53c2164fd9fde1087b7d449514baa38c418b1f6bc4bac /usr/bin/composer /usr/local/bin/composer
# Install project dependencies
COPY composer.json composer.lock package.json package-lock.json ./
RUN composer install --prefer-dist --no-interaction --no-scripts
RUN npm ci
# Copy application code (can be overridden by a volume mount in local dev)
COPY . .
# Setup entrypoint
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["apache2-foreground"]
# ====== Stage 3: Builder ======
FROM dev AS builder
RUN composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction --no-scripts
RUN npm ci --omit=dev
# npm build for production assets can be done here.
# ====== Stage 4: Prod ======
# skips dev dependencies and build tools, copies pre-compiled dependencies from builder.
FROM base AS prod
ARG DEBIAN_FRONTEND=noninteractive
# Package management
RUN apt-get update && \
apt-get install -y --no-install-recommends libonig5 libxml2 libxslt1.1 libzip5 && \
apt-mark manual libonig5 libxml2 libxslt1.1 libzip5 && \
apt-get purge -y libonig-dev libxml2-dev libxslt-dev libzip-dev linux-libc-dev $PHPIZE_DEPS && \
apt-get autoremove -y --purge && \
rm -rf /var/lib/apt/lists/*
# User and directory setup
RUN useradd -r -u 1000 -g www-data appuser
RUN mkdir -p /var/www/html/xml /var/www/html/storage
RUN chown -R appuser:www-data /var/www/html
# Copy built assets
COPY --from=builder --chown=appuser:www-data /var/www/html /var/www/html
# storage/ is dockerignored, so a named volume mounted here would otherwise be
# created empty as root:root. Seed the dirs in the image: Docker copies
# ownership and mode into each new named volume on first use (shared cache
# volume once; each variant's drafts volume independently).
RUN mkdir -p /var/www/html/storage/cache /var/www/html/storage/drafts \
&& chown appuser:www-data /var/www/html/storage \
/var/www/html/storage/cache /var/www/html/storage/drafts \
&& chmod 2775 /var/www/html/storage/cache /var/www/html/storage/drafts \
&& touch /var/www/html/storage/cache/.keep /var/www/html/storage/drafts/.keep \
&& chown appuser:www-data /var/www/html/storage/cache/.keep \
/var/www/html/storage/drafts/.keep
# Copy entrypoint
COPY --chown=appuser:www-data docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
USER appuser
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["apache2-foreground"]