แแ แแแแแ แแแแแ แแแแแแแชแแ (SPA) แแ แแก แกแขแแขแแแฃแ แ JavaScript แแ HTML แคแแแแแแแก แแแแ แแแ, แแกแแแ แกแฃแ แแแแแ แแ แกแฎแแ แ แแกแฃแ แกแแแ. แแแแก แแแแ, แ แแ แแกแแแ แแแแแแแฃแ แแ แแ แแชแแแแแ, แแแแ แแแแแแ แแแแแฅแแแงแแแแ แซแแแแแ แแแ แขแแแแ. แแแแกแแแแแก แแ แกแแแแแก แฃแแแ แแแ แแแคแ แแ แแฃแแแแช แฃแคแแกแ แกแแ แแแกแ, แแแฌแงแแแฃแแ แแแ แขแแแ GitHub แแแแ แแแแแ (แแ แแแแแกแแแแก narod.ru-แแแช แแ) แแ แแแแแแแ แแแฃแแ CDN-แแ, แ แแแแ แแชแแ Amazon S3. แแฃแแชแ แแ แกแฎแแ แ แแฆแแช แแญแแ แแแแแแ.
แแ แแญแแ แแแแแแ Docker แแแแฏแ SPA-แกแแแ แแ แแแ, แ แแแ แแแกแ แแแแแแแ แแแจแแแแ แจแแกแแซแแแแแแ แงแแคแแแแงแ แ แแแแ แช Kubernetes แแแแกแขแแ แแก แแแฌแแแแก แฌแแ แแแแแแจแ, แแกแแแ แฃแแแแ แแแแแแ แแแแแแแแแ แแก แแแแ แแขแแ, แ แแแแแกแแช แฌแแ แแแแแแแ แแ แแฅแแก แ แ แแ แแก SPA.
แแ แแแแแกแแแฆแแ แ แจแแแแแแ แกแฃแ แแแแก แแแแฎแแแแแแ แฉแแแแแแก:
- แแแแแงแแแแแแก แกแแแแ แขแแแ (แแแแ แแ แแ แ แจแแแ แแแ);
- แแแแแแแแฃแ แ แแแแ แ แแแแ แช แแแกแแแก, แแกแแแ แแแแ แแขแแฃแแ แแแฎแกแแแ แแแแก แแแแแกแแแ แแกแแ;
- แแแแคแแแฃแ แแชแแ แแแ แแแแก แชแแแแแแแแก แแแจแแแแแแ, แ แแแ แแแแแกแแฎแฃแแแแ แแแแแแงแแแแแแแแก แกแฎแแแแแกแฎแแ แแแ แแแแจแ;
- แคแแแแแแแก แงแแแแแแ แแคแแฅแขแฃแ แ แแแแแฌแแแแแ.
แแฆแแก แแ แแแขแงแแแ แ แแแแ :
- แแแฌแแแแแก แแแแแฅแกแ;
- แแ แแขแแแก แแจแแแแแ แฌแงแแ แแแแแแแ;
- แแกแฌแแแแแก แกแขแแขแแแฃแ แ แคแแแแแแ แแแ แแแแก แชแแแแแแแแก แแแกแแแแแแ;
- แแ แ แ แแฅแแ แฃแแแ, แ แแแแ แแแแฌแงแแ Docker แแแแแกแแฎแฃแแแแ แแ แงแแแแแคแ แแกแแแ.
แแ แกแขแแขแแแก แแแแแแแ แฉแแแ แแแแแชแแแแแแแก แแแแแแ แแแ แแ แกแแแแแแแแแแแก แแแแแชแแแแ แฌแแแ แแแแก แแแแกแขแ แฃแฅแชแแฃแแ แแ แแขแแแแก แแ แแแแชแแ แแแ.
แจแแแ แแแแก แแแแแกแแฎแฃแแแแแก แแแแแ
แแแแกแแแแแก, แ แแ แกแแแแแแ Docker แแแแแกแแฎแฃแแแแ แแชแแ แ แแแแแก แแงแแก, แแฅแแแ แฃแแแ แแแแชแแแ แแ แ แฌแแกแ: แแแแแแฃแ แคแแแแแ แแ แแแแแแแแแกแขแฃแ แ แแแแแก แกแฃแ แแแ. แแ แ-แแ แแ แงแแแแแแ แแแขแแ แ แกแแแแแแกแ แกแฃแ แแแ แแ แแก Alpine Linux-แแก แกแฃแ แแแ, แแกแ แ แแ, แแ แแแแก แแแแ แฉแแ. แแแแแแ แแ แจแแแซแแแแ แแแขแแแชแแแแแก, แ แแ Alpine แแ แแ แแก แจแแกแแคแแ แแกแ แฌแแ แแแแแแกแแแแก แแ แแกแแแ แจแแแซแแแแ แแแ แแแแแ แแงแแแแ. แแแแ แแ แแแ แแแแ แแ แแแกแแแ แแ แแกแแ แแก แแฅแแแแ แแ แแแแแแ แแ แแ แแแแแ แ แแ แแฃแแแแขแ แแ แแ แกแแแแแก แแแก แฌแแแแแฆแแแแ.
แแแแแแแ แคแแแ แ แแ แแฅแแแแแก, แกแฃแ แแแก 2 แแขแแแแ แแแแฌแงแแ. แแแ แแแแ แแ แแก แแแแแฎแแแ; แแแกแจแ แแแ แฉแแแ แงแแแแ แแแแฎแแแ แ แแ แแแ แแแ แแ แแ แแแแแแ แคแแแแ. แคแแแแแฃแ แแขแแแแ แแ แแฎแแแแ แแแแแแแชแแแก แกแแแแแแ แแแ แกแแแก แแแแฌแแ .
แแแแแฌแงแแ แแแแฎแแแ แ แกแฃแ แแแแ.
SPA แแแแแแแชแแแก แจแแแแแแแกแแแแก, แฉแแแฃแแแแ แแ, แแญแแ แแแแแ node.js. แแ แแแแฆแแ แแคแแชแแแแฃแ แกแฃแ แแแก, แ แแแแแกแแช แแกแแแ แแแงแแแแ npm แแ แแแ แแแก แแแแแขแแก แแแแแฏแแ แแแ. แฉแแแ แกแแฎแแแแ แแแแแแแขแแ 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
แแฅแแแ แจแแแแซแแแแ แแแแแแงแแแแ แแแแแกแแแแ แ แแแ แกแแ แแแ แ แกแขแแขแแแฃแ แ แจแแแแแ แกแแก แแแกแแแ แชแแแแแแแ. แแ แแแฉแแแฃแแ แแแ nginx-แแแ แแฃแจแแแแแก แแ แแฎแแ แแแแแแแงแแแแ.
Nginx-แก แแฅแแก แแแแแ แแก แแคแแชแแแแฃแ แ แกแฃแ แแแ, แแแแ แแ แแแก แแฅแแก แซแแแแแ แแแแ แ แแแแฃแแ แแแ แขแแแ แกแขแแขแแแฃแ แ แแแแแฌแแแแแแกแแแแก. แ แแแแแ แแแแแแแ แจแแแแก แแแฌแแแแแแจแ, แจแแแแซแแแแ แแแฎแแ แกแแแชแแแแฃแ แ แแฃแแแ แแ แแคแแชแแแแฃแ แ 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-แแ, แแ แแฅแแแแ แแแขแแ แแแแชแแแก แแฎแแ แแแญแแ แ แแ แแ แแแแแ แกแฎแแ. แแแแ แแ แฉแแแ แแแ แกแแ แจแแซแแแแก แแ แแขแแแก แแแแแ แแแแแ แจแแแฃแแจแฃแแ แคแแแแแแแก แแแแ แชแแแแแแก, แ แแช แแแแแ แฃแคแ แ แแคแแฅแขแฃแ แแ แแแแ แ 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.แจ
#!/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$|.ttf
quot;); 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;"]
แแฎแแ แแแฆแแแฃแแ แกแฃแ แแแแก แแฌแงแแแ แแ แแแแแงแแแแแ แจแแกแแซแแแแแแแ แกแแแแ.
แฌแงแแ แ: www.habr.com