Single-page Application (SPA) β ΡΡΠΎ Π½Π°Π±ΠΎΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ JavaScript ΠΈ HTML ΡΠ°ΠΉΠ»ΠΎΠ², Π° ΡΠ°ΠΊ ΠΆΠ΅ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ ΠΈ Π΄ΡΡΠ³ΠΈΡ ΡΠ΅ΡΡΡΡΠΎΠ². ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ΠΈ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ, ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°ΡΡ ΠΈΡ Π² ΠΈΠ½ΡΠ΅ΡΠ½Π΅ΡΠ΅ ΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π΄Π΅ΡΡΠ²ΡΡ ΠΈ Π΄Π°ΠΆΠ΅ Π±Π΅ΡΠΏΠ»Π°ΡΠ½ΡΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ², Π½Π°ΡΠΈΠ½Π°Ρ Ρ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ GitHub Pages (Π° Π΄Π»Ρ ΠΊΠΎΠ³ΠΎ-ΡΠΎ Π΄Π°ΠΆΠ΅ Ρ narod.ru) ΠΈ Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Ρ CDN Π²ΡΠΎΠ΄Π΅ Amazon S3. ΠΠ΄Π½Π°ΠΊΠΎ ΠΌΠ½Π΅ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π΄ΡΡΠ³ΠΎΠ΅.
ΠΠ½Π΅ Π½ΡΠΆΠ΅Π½ Π±ΡΠ» Docker-ΠΎΠ±ΡΠ°Π· Ρ SPA, ΡΡΠΎΠ±Ρ Π΅Π³ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΊΠ°ΠΊ Π² ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π΅ Π² ΡΠΎΡΡΠ°Π²Π΅ Kubernetes-ΠΊΠ»Π°ΡΡΠ΅ΡΠ°, ΡΠ°ΠΊ ΠΈ Π½Π° ΠΌΠ°ΡΠΈΠ½Π΅ back-end ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ½ΡΡΠΈΡ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ, ΡΡΠΎ ΡΠ°ΠΊΠΎΠ΅ SPA.
Π― Π΄Π»Ρ ΡΠ΅Π±Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠ» ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΊ ΠΎΠ±ΡΠ°Π·Ρ:
- ΠΏΡΠΎΡΡΠΎΡΠ° Π² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ (Π½ΠΎ Π½Π΅ Π² ΡΠ±ΠΎΡΠΊΠ΅);
- ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ ΠΊΠ°ΠΊ Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ Π΄ΠΈΡΠΊΠ°, ΡΠ°ΠΊ ΠΈ Ρ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ RAM;
- Π½Π°ΡΡΡΠΎΠΉΠΊΠ° ΡΠ΅ΡΠ΅Π· ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ, ΡΡΠΎΠ±Ρ ΠΎΠ±ΡΠ°Π· ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΡΠ°Π·Π½ΡΡ ΡΡΠ΅Π΄Π°Ρ ;
- ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½Π°Ρ ΡΠ°Π·Π΄Π°ΡΠ° ΡΠ°ΠΉΠ»ΠΎΠ².
Π‘Π΅Π³ΠΎΠ΄Π½Ρ Ρ ΡΠ°ΡΡΠΊΠ°ΠΆΡ ΠΊΠ°ΠΊ:
- Π²ΡΠΏΠΎΡΡΠΎΡΠΈΡΡ nginx;
- ΡΠΎΠ±ΡΠ°ΡΡ brotli ΠΈΠ· ΠΈΡΡ ΠΎΠ΄Π½ΠΈΠΊΠΎΠ²;
- Π½Π°ΡΡΠΈΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ;
- Π½Ρ ΠΈ ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ ΠΊΠ°ΠΊ ΡΠΎΠ±ΡΠ°ΡΡ ΠΈΠ· Π²ΡΠ΅Π³ΠΎ ΡΡΠΎΠ³ΠΎ Docker-ΠΎΠ±ΡΠ°Π·.
Π¦Π΅Π»Ρ ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠΈ ΠΏΠΎΠ΄Π΅Π»ΠΈΡΡΡΡ ΠΌΠΎΠΈΠΌ ΠΎΠΏΡΡΠΎΠΌ ΠΈ ΡΠΏΡΠΎΠ²ΠΎΡΠΈΡΠΎΠ²Π°ΡΡ ΠΎΠΏΡΡΠ½ΡΡ ΡΡΠ°ΡΡΠ½ΠΈΠΊΠΎΠ² ΡΠΎΠΎΠ±ΡΠ΅ΡΡΠ²Π° Π½Π° ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠ²Π½ΡΡ ΠΊΡΠΈΡΠΈΠΊΡ.
Π‘Π±ΠΎΡΠΊΠ° ΠΎΠ±ΡΠ°Π·Π° Π΄Π»Ρ ΡΠ±ΠΎΡΠΊΠΈ
Π§ΡΠΎΠ±Ρ ΡΠΈΠ½Π°Π»ΡΠ½ΡΠΉ Docker-ΠΎΠ±ΡΠ°Π· ΠΏΠΎΠ»ΡΡΠΈΠ»ΡΡ ΠΌΠ°Π»Π΅Π½ΡΠΊΠΈΠΌ ΠΏΠΎ ΡΠ°Π·ΠΌΠ΅ΡΡ, Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΈΠ΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ Π΄Π²ΡΡ ΠΏΡΠ°Π²ΠΈΠ»: ΠΌΠΈΠ½ΠΈΠΌΡΠΌ ΡΠ»ΠΎΡΠ² ΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΡΡΠΈΡΠ½ΡΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π·. ΠΠ΄Π½ΠΈΠΌ ΠΈΠ· ΡΠ°ΠΌΡΡ ΠΌΠ°Π»Π΅Π½ΡΠΊΠΈΡ Π±Π°Π·ΠΎΠ²ΡΡ ΠΎΠ±ΡΠ°Π·ΠΎΠ² ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠ°Π· Alpine Linux, ΠΏΠΎΡΡΠΎΠΌΡ ΠΈΠΌΠ΅Π½Π½ΠΎ Π΅Π³ΠΎ Ρ ΠΈ Π²ΡΠ±Π΅ΡΡ. ΠΡΠΎ-ΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π²ΠΎΠ·ΡΠ°Π·ΠΈΡΡ, ΡΡΠΎ Alpine Π½Π΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π° ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΎΠΊΠ°ΠΆΠ΅ΡΡΡ ΠΏΡΠ°Π². ΠΠΎ Π»ΠΈΡΠ½ΠΎ Ρ ΠΌΠ΅Π½Ρ Ρ Π½ΠΈΠΌ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»ΠΎ ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΠΈ Π½ΠΈΠΊΠ°ΠΊΠΈΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΠΏΡΠΎΡΠΈΠ² Π½Π΅Π³ΠΎ Π½Π΅Ρ.
Π§ΡΠΎΠ±Ρ Π±ΡΠ»ΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡΠ΅ ΡΠ»ΠΎΡΠ², Ρ Π±ΡΠ΄Ρ ΡΠΎΠ±ΠΈΡΠ°ΡΡ ΠΎΠ±ΡΠ°Π· Π² 2 ΡΡΠ°ΠΏΠ°. ΠΠ΅ΡΠ²ΡΠΉ β ΡΠ΅ΡΠ½ΠΎΠ²ΠΎΠΉ, Π² Π½ΡΠΌ ΠΎΡΡΠ°Π½ΡΡΡΡ Π²ΡΠ΅ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΡΠ΅ ΡΡΠΈΠ»ΠΈΡΡ ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ. Π Π² ΡΠΈΡΡΠΎΠ²ΠΎΠΉ Ρ Π·Π°ΠΏΠΈΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΈΠ½Π°Π»ΡΠ½ΡΡ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
ΠΠ°ΡΠ½ΡΠΌ ΡΠΎ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°ΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π·Π°.
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ SPA-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΎΠ±ΡΡΠ½ΠΎ, Π½ΡΠΆΠ΅Π½ node.js. Π― Π²ΠΎΠ·ΡΠΌΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΠΎΠ±ΡΠ°Π· Π² ΠΊΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ΅ Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΡΠ°ΠΊ ΠΆΠ΅ Π΅ΡΡΡ ΠΏΠ°ΠΊΠ΅ΡΠ½ΡΠ΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅ΡΡ npm ΠΈ yarn. ΠΡ ΡΠ΅Π±Ρ Ρ Π΄ΠΎΠ±Π°Π²Π»Ρ node-gyp, ΠΊΠΎΡΠΎΡΡΠΉ Π½ΡΠΆΠ΅Π½ Π΄Π»Ρ ΡΠ±ΠΎΡΠΊΠΈ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ npm-ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², ΠΈ ΠΊΠΎΠΌΠΏΡΠ΅ΡΡΠΎΡ Brotli ΠΎΡ Google, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ³ΠΎΠ΄ΠΈΡΡΡ Π½Π°ΠΌ ΠΏΠΎΠ·ΠΆΠ΅.
Dockerfile Ρ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΡΠΌΠΈ.
# ΠΠ°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π·
FROM node:12-alpine
LABEL maintainer="Aleksey Maydokin <[email protected]>"
ENV BROTLI_VERSION 1.0.7
# ΠΠ°ΠΊΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½ΡΠΆΠ½Ρ, ΡΡΠΎΠ±Ρ ΡΠΎΠ±ΡΠ°ΡΡ ΠΈΠ· ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΎΠ² Brotli
RUN apk add --no-cache --virtual .build-deps
bash
gcc
libc-dev
make
linux-headers
cmake
curl
&& mkdir -p /usr/src
# ΠΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ Brotli ΡΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΈΠ· ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
&& curl -LSs https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz | tar xzf - -C /usr/src
&& cd /usr/src/brotli-$BROTLI_VERSION
# ΠΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΠΌ Brotli
&& ./configure-cmake --disable-debug && make -j$(getconf _NPROCESSORS_ONLN) && make install
# ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ node-gyp
&& yarn global add node-gyp
# Π£Π±ΠΈΡΠ°Π΅ΠΌ Π·Π° ΡΠΎΠ±ΠΎΠΉ ΠΌΡΡΠΎΡ
&& apk del .build-deps && yarn cache clean && rm -rf /usr/src
Π£ΠΆΠ΅ Π·Π΄Π΅ΡΡ Ρ Π±ΠΎΡΡΡΡ Π·Π° ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΠ·ΠΌ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΎΠ±ΡΠ°Π· ΡΠΎΠ±ΠΈΡΠ°Π΅ΡΡΡ ΠΎΠ΄Π½ΠΎΠΉ Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ.
ΠΠΎΡΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ ΡΡΡ:
nginx
ΠΠ»Ρ ΡΠ°Π·Π΄Π°ΡΠΈ ΡΡΠ°ΡΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠ±ΠΎΠΉ web-ΡΠ΅ΡΠ²Π΅Ρ. Π― ΠΏΡΠΈΠ²ΡΠΊ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ nginx, ΠΏΠΎΡΡΠΎΠΌΡ ΠΈ ΡΠ΅ΠΉΡΠ°Ρ Π±ΡΠ΄Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ.
Π£ nginx Π΅ΡΡΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΡΠΉ Docker-ΠΎΠ±ΡΠ°Π·, ΠΎΠ΄Π½Π°ΠΊΠΎ Π΄Π»Ρ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ°Π·Π΄Π°ΡΠΈ ΡΡΠ°ΡΠΈΠΊΠΈ Π² Π½ΡΠΌ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΌΠ½ΠΎΠ³ΠΎ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ. ΠΠ°ΠΊΠΈΠ΅ ΠΈΠΌΠ΅Π½Π½ΠΎ Π²ΠΊΠ»ΡΡΠ΅Π½Ρ Π² ΠΏΠΎΡΡΠ°Π²ΠΊΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ ΠΈΠ»ΠΈ ΠΆΠ΅ Π² ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΌ Dockerfile.
$ docker run —rm nginx:1-alpine nginx -V
nginx version: nginx/1.17.9
built by gcc 8.3.0 (Alpine 8.3.0)
built with OpenSSL 1.1.1d 10 Sep 2019
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-perl_modules_path=/usr/lib/perl5/vendor_perl --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-Os -fomit-frame-pointer' --with-ld-opt=-Wl,--as-needed
Π― Π²ΠΎΠ·ΡΠΌΡ Π·Π° ΠΎΡΠ½ΠΎΠ²Ρ Dockerfile, Π½ΠΎ ΠΎΡΡΠ°Π²Π»Ρ Π² Π½ΡΠΌ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎ, ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ Π΄Π»Ρ ΡΠ°Π·Π΄Π°ΡΠΈ ΡΡΠ°ΡΠΈΠΊΠΈ. ΠΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π½Π΅ ΡΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΠΎ HTTPS, Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΡ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄ΡΡΠ³ΠΎΠ΅. ΠΠ°ΡΠΎ ΠΌΠΎΡ Π²Π΅ΡΡΠΈΡ ΡΠΌΠΎΠΆΠ΅Ρ ΡΠ°Π·Π΄Π°Π²Π°ΠΉ ΡΠ°ΠΉΠ»Ρ, ΡΠΆΠ°ΡΡΠ΅ Π°Π»Π³ΠΎΡΠΈΡΠΌΠΎΠΌ Brotli, ΠΊΠΎΡΠΎΡΡΠΉ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½Π΅Π΅, ΡΠ΅ΠΌ gzip. Π‘ΠΆΠΈΠΌΠ°ΡΡ ΡΠ°ΠΉΠ»Ρ Π±ΡΠ΄Π΅ΠΌ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·, Π΄Π΅Π»Π°ΡΡ ΡΡΠΎ Π½Π° Π»Π΅ΡΡ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.
ΠΠΎΡ ΠΊΠ°ΠΊΠΎΠΉ Dockerfile Ρ ΠΌΠ΅Π½Ρ ΠΏΠΎΠ»ΡΡΠΈΠ»ΡΡ. ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Π½Π° ΡΡΡΡΠΊΠΎΠΌ β ΠΌΠΎΠΈ, Π½Π° Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠΌ β ΠΈΠ· ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π°.
Dockerfile
# ΠΠ°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· ΡΠ½ΠΎΠ²Π° Alpine
FROM alpine:3.9
LABEL maintainer="Aleksey Maydokin <[email protected]>"
ENV NGINX_VERSION 1.16.0
ENV NGX_BROTLI_VERSION 0.1.2
ENV BROTLI_VERSION 1.0.7
RUN set -x
&& addgroup -S nginx
&& adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx
# Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΠΏΠ°ΠΊΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½ΡΠΆΠ½Ρ ΡΡΠΎΠ±Ρ ΡΠΎΠ±ΡΠ°ΡΡ nginx ΠΈ ΠΌΠΎΠ΄ΡΠ»Ρ ngx_brotli ΠΊ Π½Π΅ΠΌΡ
&& apk add --no-cache --virtual .build-deps
gcc
libc-dev
make
linux-headers
curl
&& mkdir -p /usr/src
# Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ
&& curl -LSs https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz | tar xzf - -C /usr/src
&& curl -LSs https://github.com/eustas/ngx_brotli/archive/v$NGX_BROTLI_VERSION.tar.gz | tar xzf - -C /usr/src
&& curl -LSs https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz | tar xzf - -C /usr/src
&& rm -rf /usr/src/ngx_brotli-$NGX_BROTLI_VERSION/deps/brotli/
&& ln -s /usr/src/brotli-$BROTLI_VERSION /usr/src/ngx_brotli-$NGX_BROTLI_VERSION/deps/brotli
&& cd /usr/src/nginx-$NGINX_VERSION
&& CNF="
--prefix=/etc/nginx
--sbin-path=/usr/sbin/nginx
--modules-path=/usr/lib/nginx/modules
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
--http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--user=nginx
--group=nginx
--without-http_ssi_module
--without-http_userid_module
--without-http_access_module
--without-http_auth_basic_module
--without-http_mirror_module
--without-http_autoindex_module
--without-http_geo_module
--without-http_split_clients_module
--without-http_referer_module
--without-http_rewrite_module
--without-http_proxy_module
--without-http_fastcgi_module
--without-http_uwsgi_module
--without-http_scgi_module
--without-http_grpc_module
--without-http_memcached_module
--without-http_limit_conn_module
--without-http_limit_req_module
--without-http_empty_gif_module
--without-http_browser_module
--without-http_upstream_hash_module
--without-http_upstream_ip_hash_module
--without-http_upstream_least_conn_module
--without-http_upstream_keepalive_module
--without-http_upstream_zone_module
--without-http_gzip_module
--with-http_gzip_static_module
--with-threads
--with-compat
--with-file-aio
--add-dynamic-module=/usr/src/ngx_brotli-$NGX_BROTLI_VERSION
"
# Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ
&& ./configure $CNF
&& make -j$(getconf _NPROCESSORS_ONLN)
&& make install
&& rm -rf /usr/src/
# Π£Π΄Π°Π»ΡΠ΅ΠΌ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠΉ brotli ΠΌΠΎΠ΄ΡΠ»Ρ, ΠΎΡΡΠ°Π²Π»ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ
&& rm /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so
&& sed -i '$ d' /etc/apk/repositories
# Bring in gettext so we can get `envsubst`, then throw
# the rest away. To do this, we need to install `gettext`
# then move `envsubst` out of the way so `gettext` can
# be deleted completely, then move `envsubst` back.
&& apk add --no-cache --virtual .gettext gettext
&& mv /usr/bin/envsubst /tmp/
&& runDeps="$(
scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst
| awk '{ gsub(/,/, "nso:", $2); print "so:" $2 }'
| sort -u
| xargs -r apk info --installed
| sort -u
)"
&& apk add --no-cache $runDeps
&& apk del .build-deps
&& apk del .gettext
&& mv /tmp/envsubst /usr/local/bin/
# Bring in tzdata so users could set the timezones through the environment
# variables
&& apk add --no-cache tzdata
# forward request and error logs to docker log collector
&& ln -sf /dev/stdout /var/log/nginx/access.log
&& ln -sf /dev/stderr /var/log/nginx/error.log
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
STOPSIGNAL SIGTERM
CMD ["nginx", "-g", "daemon off;"]
Π― ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΠΎΠΏΡΠ°Π²Π»Ρ nginx.conf, ΡΡΠΎΠ±Ρ gzip ΠΈ brotli Π±ΡΠ»ΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. Π’Π°ΠΊ ΠΆΠ΅ Π²ΠΊΠ»ΡΡΡ ΠΊΡΡΠΈΡΡΡΡΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Π²Π΅Π΄Ρ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ ΡΠ°Π·Π΄Π°Π²Π°ΡΡΡΡ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΌΠ΅Π½ΡΡΡΠ°ΡΡΡ ΡΡΠ°ΡΠΈΠΊΠ°. Π ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌ ΡΡΡΠΈΡ ΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π°Π΄ΡΠ΅ΡΠ°ΡΠΈΡ Π²ΡΠ΅Ρ 404 Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° index.html, ΡΡΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π»Ρ Π½Π°Π²ΠΈΠ³Π°ΡΠΈΠΈ Π² SPA.
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module /usr/lib/nginx/modules/ngx_http_brotli_static_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip_static on;
brotli_static on;
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root html;
try_files $uri /index.html;
etag on;
expires max;
add_header Cache-Control public;
location = /index.html {
expires 0;
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
}
}
}
Π‘ΠΊΠ°ΡΠ°ΡΡ Π³ΠΎΡΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· ΠΌΠΎΠΆΠ½ΠΎ Π·Π΄Π΅ΡΡ:
Π£ΡΠΈΠΌ ΡΡΠ°ΡΠΈΠΊΡ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ
ΠΠ»Ρ ΡΠ΅Π³ΠΎ Π² SPA ΠΌΠΎΠ³ΡΡ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ? ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠΊΠ°Π·Π°ΡΡ ΠΊΠ°ΠΊΠΎΠΉ RESTful API ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ. ΠΠ±ΡΡΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π΄Π»Ρ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π² SPA Π½Π° ΡΡΠ°ΠΏΠ΅ ΡΠ±ΠΎΡΠΊΠΈ. ΠΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ ΡΡΠΎ-ΡΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ, ΡΠΎ ΠΏΡΠΈΠ΄ΡΡΡΡ ΠΏΠ΅ΡΠ΅ΡΠΎΠ±ΡΠ°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π― ΡΡΠΎΠ³ΠΎ Π½Π΅ Ρ ΠΎΡΡ. Π― Ρ ΠΎΡΡ ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ±ΠΈΡΠ°Π»ΠΎΡΡ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· Π½Π° ΡΡΠ°Π΄ΠΈΠΈ CI, Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠΈΡΠΎΠ²Π°Π»ΠΎΡΡ ΡΡΠΎΠ»ΡΠΊΠΎ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π½ΡΠΆΠ½ΠΎ, Π½Π° ΡΡΠ°Π΄ΠΈΠΈ CD Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ.
Π Π°Π·ΡΠΌΠ΅Π΅ΡΡΡ, ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ ΡΠ°ΠΌΠΈ ΠΏΠΎ ΡΠ΅Π±Π΅ Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ. ΠΠΎΡΡΠΎΠΌΡ, ΠΏΡΠΈΠ΄ΡΡΡΡ ΠΏΠΎΠΉΡΠΈ Π½Π° Ρ ΠΈΡΡΠΎΡΡΡ. Π ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠΌ ΠΎΠ±ΡΠ°Π·Π΅ Ρ Π±ΡΠ΄Ρ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π½Π΅ nginx, Π° ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ shell-ΡΠΊΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΎΡΠΈΡΠ°Π΅Ρ ΠΏΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ, Π·Π°ΠΏΠΈΡΠΈΡ ΠΈΡ Π² ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ, ΡΠΎΠΆΠΌΡΡ ΠΈΡ ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ nginx.
ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π² Dockerfile ΠΏΡΠ΅Π΄ΡΡΠΌΠΎΡΡΠ΅Π½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ENTRYPOINT. ΠΠ΅ΡΠ΅Π΄Π°Π΄ΠΈΠΌ Π΅ΠΌΡ Π²ΠΎΡ ΡΠ°ΠΊΠΎΠΉ ΡΠΊΡΠΈΠΏΡ (Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Angular):
docker-entrypoint.sh
#!/bin/sh set -e FLAG_FILE="/configured" TARGET_DIR="/etc/nginx/html" replace_vars () { ENV_VARS='$(awk 'BEGIN{for(v in ENVIRON) print "
quot;v}')'
# Π Angular ΠΈΡΠ΅ΠΌ ΠΏΠ»Π΅ΠΉΡΡ ΠΎΠ»Π΄Π΅ΡΡ Π² main-ΡΠ°ΠΉΠ»Π°Ρ
for f in "$TARGET_DIR"/main*.js; do
# envsubst Π·Π°ΠΌΠ΅Π½ΡΠ΅Ρ Π² ΡΠ°ΠΉΠ»Π°Ρ ΠΏΠ»Π΅ΠΉΡΡ ΠΎΠ»Π΄Π΅ΡΡ Π½Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈΠ· ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ
echo "$(envsubst "$ENV_VARS" < "$f")" > "$f"
done
}
compress () {
for i in $(find "$TARGET_DIR" | grep -E ".css$|.html$|.js$|.svg$|.txt$|.ttfquot;); do
# ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΡΡΠ΅ΠΏΠ΅Π½Ρ ΡΠΆΠ°ΡΠΈΡ
gzip -9kf "$i" && brotli -fZ "$i"
done
}
if [ "$1" = 'nginx' ]; then
# Π€Π»Π°Π³ Π½ΡΠΆΠ΅Π½, ΡΡΠΎΠ±Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΠΊΡΠΈΠΏΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈ ΡΠ°ΠΌΠΎΠΌ ΠΏΠ΅ΡΠ²ΠΎΠΌ Π·Π°ΠΏΡΡΠΊΠ΅
if [ ! -e "$FLAG_FILE" ]; then
echo "Running init script"
echo "Replacing env vars"
replace_vars
echo "Compressing files"
compress
touch $FLAG_FILE
echo "Done"
fi
fi
exec "$@"
Π§ΡΠΎΠ±Ρ ΡΠΊΡΠΈΠΏΡ ΡΠ΄Π΅Π»Π°Π» ΡΠ²ΠΎΡ Π΄Π΅Π»ΠΎ, Π² js-ΡΠ°ΠΉΠ»Π°Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π½Π°Π΄ΠΎ ΠΏΠΈΡΠ°ΡΡ Π²ΠΎΡ Π² ΡΠ°ΠΊΠΎΠΌ Π²ΠΈΠ΄Π΅:${API_URL}
.Π‘ΡΠΎΠΈΡ ΠΎΡΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ SPA ΠΏΡΠΈ ΡΠ±ΠΎΡΠΊΠ΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΊ ΡΠ²ΠΎΠΈΠΌ ΡΠ°ΠΉΠ»Π°ΠΌ Ρ ΡΡΠΈ. ΠΡΠΎ Π½ΡΠΆΠ½ΠΎ, ΡΡΠΎΠ±Ρ Π±ΡΠ°ΡΠ·Π΅Ρ ΠΌΠΎΠ³ ΡΠΌΠ΅Π»ΠΎ Π·Π°ΠΊΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΉΠ» Π½Π° Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΡΡΠΎΠΊ. ΠΡΠ»ΠΈ ΡΠ°ΠΉΠ» Π²ΡΡ-ΡΠ°ΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡΡ, ΡΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡΡ ΠΈ Π΅Π³ΠΎ Ρ ΡΡ, ΡΡΠΎ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ Π·Π°ΡΡΠ°Π²ΠΈΡ Π±ΡΠ°ΡΠ·Π΅Ρ ΡΠΊΠ°ΡΠ°ΡΡ ΡΠ°ΠΉΠ» Π·Π°Π½ΠΎΠ²ΠΎ.
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π² ΠΌΠΎΡΠΌ ΠΌΠ΅ΡΠΎΠ΄Π΅, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ Π½Π΅ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Ρ ΡΡΠ° ΡΠ°ΠΉΠ»Π°, Π° Π·Π½Π°ΡΠΈΡ ΠΈΠ½Π²Π°Π»ΠΈΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΡΡ Π±ΡΠ°ΡΠ·Π΅ΡΠ° Π½Π°Π΄ΠΎ ΠΊΠ°ΠΊΠΈΠΌ-ΡΠΎ Π΄ΡΡΠ³ΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ. Π£ ΠΌΠ΅Π½Ρ ΡΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π½Π΅Ρ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΡΠ°Π·Π½ΡΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΠ°Π·Π²ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡΡΡ Π² ΡΠ°Π·Π½ΡΡ ΡΡΠ΅Π΄Π°Ρ .
Π‘ΠΎΠ±ΠΈΡΠ°Π΅ΠΌ ΡΠΈΠ½Π°Π»ΡΠ½ΡΠΉ ΠΎΠ±ΡΠ°Π·
ΠΠ°ΠΊΠΎΠ½Π΅Ρ-ΡΠΎ.
Dockerfile
# ΠΠ΅ΡΠ²ΡΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· Π΄Π»Ρ ΡΠ±ΠΎΡΠΊΠΈ FROM alexxxnf/spa-builder as builder # Π§ΡΠΎΠ±Ρ ΡΡΡΠΊΡΠΈΠ²Π½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΡΡ Docker-Π°, ΡΠ½Π°ΡΠ°Π»Π° ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠΎΠ»ΡΠΊΠΎ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ COPY ./package.json ./package-lock.json /app/ RUN cd /app && npm ci --no-audit # ΠΠΎΡΠΎΠΌ ΡΠΎΠ±ΠΈΡΠ°Π΅ΠΌ ΡΠ°ΠΌΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ COPY . /app RUN cd /app && npm run build -- --prod --configuration=docker # ΠΡΠΎΡΠΎΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π· Π΄Π»Ρ ΡΠ°Π·Π΄Π°ΡΠΈ FROM alexxxnf/nginx-spa # ΠΠ°Π±ΠΈΡΠ°Π΅ΠΌ ΠΈΠ· ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π·Π° ΡΠ½Π°ΡΠ°Π»Π° ΠΊΠΎΠΌΠΏΡΠ΅ΡΡΠΎΡ COPY --from=builder /usr/local/bin/brotli /usr/local/bin # ΠΠΎΡΠΎΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΡΠ΄ΠΎ-ΡΠΊΡΠΈΠΏΡ COPY ./docker/docker-entrypoint.sh /docker-entrypoint.sh # Π Π² ΠΊΠΎΠ½ΡΠ΅ Π·Π°Π±ΠΈΡΠ°Π΅ΠΌ ΡΠ°ΠΌΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ COPY --from=builder /app/dist/app /etc/nginx/html/ ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["nginx", "-g", "daemon off;"]
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΠ»ΡΡΠΈΠ²ΡΠΈΠΉΡΡ ΠΎΠ±ΡΠ°Π· ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ±ΡΠ°ΡΡ ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π³Π΄Π΅-ΡΠ³ΠΎΠ΄Π½ΠΎ.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com