рд╕рд┐рдВрдЧрд▓-рдкреЗрдЬ рдПрдкреНрд▓рд┐рдХреЗрд╢рди (рдПрд╕рдкреАрдП) рд╕реНрдерд┐рд░ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ HTML рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЫрд╡рд┐рдпреЛрдВ рдФрд░ рдЕрдиреНрдп рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдСрдирд▓рд╛рдЗрди рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╕рд╕реНрддреА рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдореБрдлреНрдд рд╕реЗрд╡рд╛рдПрдВ рднреА рд╣реИрдВ, рдЬреЛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг GitHub рдкреЗрдЬ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВ (рдФрд░ рдХреБрдЫ рдХреЗ рд▓рд┐рдП naroad.ru рдХреЗ рд╕рд╛рде рднреА) рдФрд░ Amazon S3 рдЬреИрд╕реЗ CDN рддрдХ рд╕рдорд╛рдкреНрдд рд╣реЛрддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореБрдЭреЗ рдХреБрдЫ рдФрд░ рдЪрд╛рд╣рд┐рдП рдерд╛ред
рдореБрдЭреЗ рдПрд╕рдкреАрдП рдХреЗ рд╕рд╛рде рдПрдХ рдбреЙрдХрд░ рдЫрд╡рд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА рддрд╛рдХрд┐ рдЗрд╕реЗ рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреНрд▓рд╕реНрдЯрд░ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдФрд░ рдмреИрдХ-рдПрдВрдб рдбреЗрд╡рд▓рдкрд░ рдХреА рдорд╢реАрди рдкрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдЬрд┐рд╕реЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрд╕рдкреАрдП рдХреНрдпрд╛ рд╣реИред
рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЫрд╡рд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдБ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рд╣реИрдВ:
- рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА (рд▓реЗрдХрд┐рди рдЕрд╕реЗрдВрдмрд▓реА рдирд╣реАрдВ);
- рдбрд┐рд╕реНрдХ рдФрд░ рд░реИрдо рджреЛрдиреЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдиреНрдпреВрдирддрдо рдЖрдХрд╛рд░;
- рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддрд╛рдХрд┐ рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ;
- рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рд╕рдмрд╕реЗ рдХреБрд╢рд▓ рд╡рд┐рддрд░рдгред
рдЖрдЬ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХреИрд╕реЗ:
- рдЖрдВрдд nginx;
- рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдмреНрд░реЛрдЯрд▓реА рдмрдирд╛рдПрдВ;
- рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╕рд┐рдЦрд╛рдПрдВ;
- рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рдм рд╕реЗ рдПрдХ рдбреЙрдХрд░ рдЫрд╡рд┐ рдХреИрд╕реЗ рдмрдирд╛рдИ рдЬрд╛рдПред
рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдФрд░ рдЕрдиреБрднрд╡реА рд╕рдореБрджрд╛рдп рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рдХреЛ рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд░рдирд╛ рд╣реИред
рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд▓рд┐рдП рдПрдХ рдЫрд╡рд┐ рдмрдирд╛рдирд╛
рдЕрдВрддрд┐рдо рдбреЙрдХрд░ рдЫрд╡рд┐ рдХреЛ рдЖрдХрд╛рд░ рдореЗрдВ рдЫреЛрдЯрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рджреЛ рдирд┐рдпрдореЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛: рдиреНрдпреВрдирддрдо рдкрд░рддреЗрдВ рдФрд░ рдПрдХ рдиреНрдпреВрдирддрдо рдЖрдзрд╛рд░ рдЫрд╡рд┐ред рд╕рдмрд╕реЗ рдЫреЛрдЯреА рдЖрдзрд╛рд░ рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдЕрд▓реНрдкрд╛рдЗрди рд▓рд┐рдирдХреНрд╕ рдЫрд╡рд┐ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рдЪреБрдиреВрдВрдЧрд╛ред рдХреБрдЫ рд▓реЛрдЧ рдпрд╣ рддрд░реНрдХ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЕрд▓реНрдкрд╛рдЗрди рдЙрддреНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ, рдФрд░ рд╡реЗ рд╕рд╣реА рднреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡реНрдпрдХреНрддрд┐рдЧрдд рддреМрд░ рдкрд░ рдореБрдЭреЗ рдЙрдирд╕реЗ рдХрднреА рдХреЛрдИ рджрд┐рдХреНрдХрдд рдирд╣реАрдВ рд░рд╣реА рдФрд░ рдЙрдирдХреЗ рдЦрд┐рд▓рд╛рдл рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИ.
рдХрдо рдкрд░рддреЗрдВ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЫрд╡рд┐ рдХреЛ 2 рдЪрд░рдгреЛрдВ рдореЗрдВ рдПрдХрддреНрд░рд┐рдд рдХрд░реВрдБрдЧрд╛ред рдкрд╣рд▓рд╛ рдПрдХ рдбреНрд░рд╛рдлреНрдЯ рд╣реИ; рд╕рднреА рд╕рд╣рд╛рдпрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдПрдБ рдФрд░ рдЕрд╕реНрдерд╛рдпреА рдлрд╝рд╛рдЗрд▓реЗрдВ рдЗрд╕рдореЗрдВ рд░рд╣реЗрдВрдЧреАред рдФрд░ рдЕрдВрддрд┐рдо рдЪрд░рдг рдореЗрдВ рдореИрдВ рдХреЗрд╡рд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рд╣реА рд▓рд┐рдЦреВрдВрдЧрд╛ред
рдЖрдЗрдП рд╕рд╣рд╛рдпрдХ рдЫрд╡рд┐ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВред
рдПрд╕рдкреАрдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЖрдорддреМрд░ рдкрд░ рдиреЛрдб.рдЬреЗрдПрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдореИрдВ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЫрд╡рд┐ рд▓реВрдВрдЧрд╛, рдЬреЛ рдПрдирдкреАрдПрдо рдФрд░ рдпрд╛рд░реНрди рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░реЛрдВ рдХреЗ рд╕рд╛рде рднреА рдЖрддреА рд╣реИред рдЕрдкрдиреА рдУрд░ рд╕реЗ, рдореИрдВ рдиреЛрдб-рдЬрд┐рдк рдЬреЛрдбрд╝реВрдВрдЧрд╛, рдЬреЛ рдХреБрдЫ рдПрдирдкреАрдПрдо рдкреИрдХреЗрдЬ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ Google рд╕реЗ рдмреНрд░реЙрдЯрд▓реА рдХрдВрдкреНрд░реЗрд╕рд░, рдЬреЛ рдмрд╛рдж рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред
рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдбреЙрдХрд░рдлрд╝рд╛рдЗрд▓ред
# ╨С╨░╨╖╨╛╨▓╤Л╨╣ ╨╛╨▒╤А╨░╨╖
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 рдХреА рдПрдХ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдбреЙрдХрд░ рдЫрд╡рд┐ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рд╕рд░рд▓ рд╕реНрдереИрддрд┐рдХ рд╡рд┐рддрд░рдг рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рдореЙрдбреНрдпреВрд▓ рд╣реИрдВред рдбрд┐рд▓реАрд╡рд░реА рдореЗрдВ рдХреМрди-рдХреМрди рд╕реЗ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЯреАрдо рдпрд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдбреЙрдХрд░рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
$ рдбреЙрдХрд░ рд░рди --рдЖрд░рдПрдо nginx:1-рдЕрд▓реНрдкрд╛рдЗрди 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
рдореИрдВ рдбреЙрдХрд░рдлрд╛рдЗрд▓ рдХреЛ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рд╡рд╣реА рдЫреЛрдбрд╝реВрдВрдЧрд╛ рдЬреЛ рд╕реНрдереИрддрд┐рдХ рд╕рд╛рдордЧреНрд░реА рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдореЗрд░рд╛ рд╕рдВрд╕реНрдХрд░рдг HTTPS рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдЧрд╛, рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдФрд░ рднреА рдмрд╣реБрдд рдХреБрдЫред рд▓реЗрдХрд┐рди рдореЗрд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдмреНрд░реЙрдЯрд▓реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рд╛рде рд╕рдВрдкреАрдбрд╝рд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛, рдЬреЛ рдХрд┐ gzip рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реИред рд╣рдо рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рдмрд╛рд░ рдХрдВрдкреНрд░реЗрд╕ рдХрд░ рджреЗрдВрдЧреЗ; рддреБрд░рдВрдд рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдпрд╣ рд╡рд╣ рдбреЙрдХрд░рдлрд╝рд╛рдЗрд▓ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВ рд╕рдорд╛рдкреНрдд рд╣реБрдЖред рд░реВрд╕реА рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдореЗрд░реА рд╣реИрдВ, рдЕрдВрдЧреНрд░реЗрдЬреА рдореЗрдВ - рдореВрд▓ рд╕реЗред
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";
}
}
}
}
рдЖрдк рддреИрдпрд╛рд░ рдЫрд╡рд┐ рдпрд╣рд╛рдВ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдВрдЦреНрдпрд┐рдХреА рдкрдврд╝рд╛рдирд╛
рдПрд╕рдкреАрдП рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрд┐рд╕ RESTful API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдЖрдорддреМрд░ рдкрд░, рд╡рд╛рдВрдЫрд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЛ рдирд┐рд░реНрдорд╛рдг рдЪрд░рдг рдореЗрдВ рдПрд╕рдкреАрдП рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдХреБрдЫ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рдпрд╣ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдпреЗред рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдПрдХ рдмрд╛рд░ рд╕реАрдЖрдИ рдЪрд░рдг рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рдП, рдФрд░ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реАрдбреА рдЪрд░рдг рдореЗрдВ рдЬрд┐рддрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдмреЗрд╢рдХ, рд╕реНрдереИрддрд┐рдХ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╕реНрд╡рдпрдВ рдХрд┐рд╕реА рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рдирд╣реАрдВ рд╕рдордЭрддреА рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдЯреНрд░рд┐рдХ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛. рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдореЗрдВ, рдореИрдВ nginx рд▓реЙрдиреНрдЪ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рдмрд▓реНрдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╢реЗрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓реЙрдиреНрдЪ рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рдкрдврд╝реЗрдЧреА, рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд┐рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд▓рд┐рдЦреЗрдЧреА, рдЙрдиреНрд╣реЗрдВ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░реЗрдЧреА, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА nginx рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдЧреАред
рдЗрд╕ рдкреНрд░рдпреЛрдЬрди рдХреЗ рд▓рд┐рдП, Dockerfile ENTRYPOINT рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЖрдЗрдП рдЙрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдПрдВрдЧреБрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ):
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$|.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}
.рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЖрдзреБрдирд┐рдХ рдПрд╕рдкреАрдП рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╕рдордп рдЕрдкрдиреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╣реИрд╢ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рддрд╛рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдлрд╝рд╛рдЗрд▓ рдХреЛ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╢ рдХрд░ рд╕рдХреЗред рдпрджрд┐ рдлрд╝рд╛рдЗрд▓ рдмрджрд▓рддреА рд╣реИ, рддреЛ рдЙрд╕рдХрд╛ рд╣реИрд╢ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░реЗрдЧрд╛ред
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореЗрд░реА рдкрджреНрдзрддрд┐ рдореЗрдВ, рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдмрджрд▓рдиреЗ рд╕реЗ рдлрд╝рд╛рдЗрд▓ рд╣реИрд╢ рдореЗрдВ рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреИрд╢ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдЕрдорд╛рдиреНрдп рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореБрдЭреЗ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддреИрдирд╛рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛
рдЕрдВрдд рдореЗрдВред
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