This repository has been archived by the owner on Nov 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDockerfile
169 lines (132 loc) · 7.47 KB
/
Dockerfile
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
# Create args for PHP extensions and PECL packages we need to install.
# This makes it easier if we want to install packages,
# as we have to install them in multiple places.
# This helps keep ou Dockerfiles DRY -> https://bit.ly/dry-code
# You can see a list of required extensions for Laravel here: https://laravel.com/docs/10.x/deployment#server-requirements
ARG PHP_EXTS="bcmath ctype fileinfo mbstring pdo pdo_mysql dom pcntl opcache"
ARG PHP_PECL_EXTS="redis"
# We need to build the Composer base to reuse packages we've installed
FROM composer:2.6 as composer_base
# We need to declare that we want to use the args in this build step
ARG PHP_EXTS
ARG PHP_PECL_EXTS
# First, create the application directory, and some auxilary directories for scripts and such
RUN mkdir -p /opt/apps/betterhm-backend /opt/apps/betterhm-backend/bin
# Next, set our working directory
WORKDIR /opt/apps/betterhm-backend
# We need to create a composer group and user, and create a home directory for it, so we keep the rest of our image safe,
# And not accidentally run malicious scripts
RUN addgroup -S composer
RUN adduser -S composer -G composer
RUN chown -R composer /opt/apps/betterhm-backend
RUN apk add --virtual build-dependencies --no-cache ${PHPIZE_DEPS} openssl ca-certificates libxml2-dev oniguruma-dev libpng-dev libjpeg-turbo-dev zlib-dev
RUN docker-php-ext-install -j$(nproc) ${PHP_EXTS}
RUN install-php-extensions gd
RUN pecl install ${PHP_PECL_EXTS}
RUN docker-php-ext-enable ${PHP_PECL_EXTS}
RUN apk del build-dependencies
# Next we want to switch over to the composer user before running installs.
# This is very important, so any extra scripts that composer wants to run,
# don't have access to the root filesystem.
# This especially important when installing packages from unverified sources.
USER composer
# Copy in our dependency files.
# We want to leave the rest of the code base out for now,
# so Docker can build a cache of this layer,
# and only rebuild when the dependencies of our application changes.
COPY --chown=composer composer.json composer.lock ./
# Install all the dependencies without running any installation scripts.
# We skip scripts as the code base hasn't been copied in yet and script will likely fail,
# as `php artisan` available yet.
# This also helps us to cache previous runs and layers.
# As long as comoser.json and composer.lock doesn't change the install will be cached.
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
# Copy in our actual source code so we can run the installation scripts we need
# At this point all the PHP packages have been installed,
# and all that is left to do, is to run any installation scripts which depends on the code base
COPY --chown=composer . .
# Now that the code base and packages are all available,
# we can run the install again, and let it run any install scripts.
RUN composer install --no-dev --prefer-dist
# For the frontend, we want to get all the Laravel files,
# and run a production compile
FROM node:lts as frontend
# We need to copy in the Laravel files to makeA everything is available to our frontend compilation
COPY --from=composer_base /opt/apps/betterhm-backend /opt/apps/betterhm-backend
WORKDIR /opt/apps/betterhm-backend
# We want to install all the NPM packages,
# and compile the Vite bundle for production
RUN npm install && \
npm run build
# For running things like migrations, and queue jobs,
# we need a CLI container.
# It contains all the Composer packages,
# and just the basic CLI "stuff" in order for us to run commands,
# be that queues, migrations, tinker etc.
FROM php:8.2-alpine as cli
# We need to declare that we want to use the args in this build step
ARG PHP_EXTS
ARG PHP_PECL_EXTS
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
WORKDIR /opt/apps/betterhm-backend
# We need to install some requirements into our image,
# used to compile our PHP extensions, as well as install all the extensions themselves.
# You can see a list of required extensions for Laravel here: https://laravel.com/docs/10.x/deployment#server-requirements
RUN apk add --virtual build-dependencies --no-cache ${PHPIZE_DEPS} openssl ca-certificates libxml2-dev oniguruma-dev libpng-dev libjpeg-turbo-dev zlib-dev && \
docker-php-ext-install -j$(nproc) ${PHP_EXTS} && \
chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions gd && \
pecl install ${PHP_PECL_EXTS} && \
docker-php-ext-enable ${PHP_PECL_EXTS} && \
apk del build-dependencies
# Next we have to copy in our code base from our initial build which we installed in the previous stage
COPY --from=composer_base /opt/apps/betterhm-backend /opt/apps/betterhm-backend
COPY --from=frontend /opt/apps/betterhm-backend/public /opt/apps/betterhm-backend/public
# We need a stage which contains FPM to actually run and process requests to our PHP application.
FROM php:8.2-fpm-alpine as fpm_server
# We need to declare that we want to use the args in this build step
ARG PHP_EXTS
ARG PHP_PECL_EXTS
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
WORKDIR /opt/apps/betterhm-backend
RUN apk add --virtual build-dependencies --no-cache ${PHPIZE_DEPS} openssl ca-certificates libxml2-dev oniguruma-dev libpng-dev libjpeg-turbo-dev zlib-dev
RUN docker-php-ext-install -j$(nproc) ${PHP_EXTS}
RUN chmod +x /usr/local/bin/install-php-extensions
RUN install-php-extensions gd
RUN pecl install ${PHP_PECL_EXTS}
RUN docker-php-ext-enable ${PHP_PECL_EXTS}
RUN apk del build-dependencies
# As FPM uses the www-data user when running our application,
# we need to make sure that we also use that user when starting up,
# so our user "owns" the application when running
USER www-data
# We have to copy in our code base from our initial build which we installed in the previous stage
COPY --from=composer_base --chown=www-data /opt/apps/betterhm-backend /opt/apps/betterhm-backend
COPY --from=frontend --chown=www-data /opt/apps/betterhm-backend/public /opt/apps/betterhm-backend/public
# We want to cache the event, routes, and views so we don't try to write them when we are in Kubernetes.
# Docker builds should be as immutable as possible, and this removes a lot of the writing of the live application.
RUN php artisan event:cache && \
php artisan route:cache && \
php artisan view:cache
# We need an nginx container which can pass requests to our FPM container,
# as well as serve any static content.
FROM nginx:alpine as web_server
WORKDIR /opt/apps/betterhm-backend
# We need to add our NGINX template to the container for startup,
# and configuration.
COPY docker/nginx.conf.template /etc/nginx/templates/default.conf.template
# Copy in ONLY the public directory of our project.
# This is where all the static assets will live, which nginx will serve for us.
COPY --from=frontend /opt/apps/betterhm-backend/public /opt/apps/betterhm-backend/public
# We need a CRON container to the Laravel Scheduler.
# We'll start with the CLI container as our base,
# as we only need to override the CMD which the container starts with to point at cron
FROM cli as cron
WORKDIR /opt/apps/betterhm-backend
# We want to create a laravel.cron file with Laravel cron settings, which we can import into crontab,
# and run crond as the primary command in the forground
RUN touch laravel.cron && \
echo "* * * * * cd /opt/apps/betterhm-backend && php artisan schedule:run" >> laravel.cron && \
crontab laravel.cron
CMD ["crond", "-l", "2", "-f"]
FROM cli