{"id":302327,"date":"2020-04-22T15:01:00","date_gmt":"2020-04-22T15:01:00","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=302327"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=302327","title":{"rendered":"Docker-\u043e\u0431\u0440\u0430\u0437 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 Single Page Application"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/498472\/\">\n<p>Single-page Application (SPA) \u2013 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 JavaScript \u0438 HTML \u0444\u0430\u0439\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u0448\u0451\u0432\u044b\u0445 \u0438 \u0434\u0430\u0436\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e GitHub Pages (\u0430 \u0434\u043b\u044f \u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u0430\u0436\u0435 \u0441 narod.ru) \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f CDN \u0432\u0440\u043e\u0434\u0435 Amazon S3. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<p>  <\/p>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b Docker-\u043e\u0431\u0440\u0430\u0437 \u0441 SPA, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u0430\u043a \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435 back-end \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 SPA.<\/p>\n<p>  <\/p>\n<p>\u042f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043e\u0431\u0440\u0430\u0437\u0443:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 (\u043d\u043e \u043d\u0435 \u0432 \u0441\u0431\u043e\u0440\u043a\u0435);<\/li>\n<li>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0434\u0438\u0441\u043a\u0430, \u0442\u0430\u043a \u0438 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f RAM;<\/li>\n<li>\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0430\u0445;<\/li>\n<li>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043b\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u044c nginx;<\/li>\n<li>\u0441\u043e\u0431\u0440\u0430\u0442\u044c brotli \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432;<\/li>\n<li>\u043d\u0430\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f;<\/li>\n<li>\u043d\u0443 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043a\u0430\u043a \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e Docker-\u043e\u0431\u0440\u0430\u0437.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0426\u0435\u043b\u044c \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043c\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0438 \u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u043a\u0440\u0438\u0442\u0438\u043a\u0443.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h3 id=\"sborka-obraza-dlya-sborki\">\u0421\u0431\u043e\u0440\u043a\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438<\/h3>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 Docker-\u043e\u0431\u0440\u0430\u0437 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u043c \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0432\u0443\u0445 \u043f\u0440\u0430\u0432\u0438\u043b: \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0441\u043b\u043e\u0451\u0432 \u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0437 Alpine Linux, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e \u044f \u0438 \u0432\u044b\u0431\u0435\u0440\u0443. \u041a\u0442\u043e-\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0440\u0430\u0437\u0438\u0442\u044c, \u0447\u0442\u043e Alpine \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430 \u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432. \u041d\u043e \u043b\u0438\u0447\u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u0441 \u043d\u0438\u043c \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0438 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0442\u0438\u0432 \u043d\u0435\u0433\u043e \u043d\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u043b\u043e\u0451\u0432, \u044f \u0431\u0443\u0434\u0443 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0437 \u0432 2 \u044d\u0442\u0430\u043f\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u2013 \u0447\u0435\u0440\u043d\u043e\u0432\u043e\u0439, \u0432 \u043d\u0451\u043c \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u0432\u0441\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b. \u0410 \u0432 \u0447\u0438\u0441\u0442\u043e\u0432\u043e\u0439 \u044f \u0437\u0430\u043f\u0438\u0448\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c SPA-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043e\u0431\u044b\u0447\u043d\u043e, \u043d\u0443\u0436\u0435\u043d node.js. \u042f \u0432\u043e\u0437\u044c\u043c\u0443 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u0432 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0435 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0430\u043a \u0436\u0435 \u0435\u0441\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u043d\u044b\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u044b npm \u0438 yarn. \u041e\u0442 \u0441\u0435\u0431\u044f \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044e node-gyp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 npm-\u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0438 \u043a\u043e\u043c\u043f\u0440\u0435\u0441\u0441\u043e\u0440 Brotli \u043e\u0442 Google, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Dockerfile \u0441 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438.<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\"># \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 FROM node:12-alpine LABEL maintainer=&quot;Aleksey Maydokin &lt;amaydokin@gmail.com&gt;&quot; ENV BROTLI_VERSION 1.0.7 # \u041f\u0430\u043a\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 Brotli RUN apk add --no-cache --virtual .build-deps \\         bash \\         gcc \\         libc-dev \\         make \\         linux-headers \\         cmake \\         curl \\     &amp;&amp; mkdir -p \/usr\/src \\     # \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 Brotli \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f     &amp;&amp; curl -LSs https:\/\/github.com\/google\/brotli\/archive\/v$BROTLI_VERSION.tar.gz | tar xzf - -C \/usr\/src \\     &amp;&amp; cd \/usr\/src\/brotli-$BROTLI_VERSION \\     # \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c Brotli     &amp;&amp; .\/configure-cmake --disable-debug &amp;&amp; make -j$(getconf _NPROCESSORS_ONLN) &amp;&amp; make install \\     # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c node-gyp     &amp;&amp; yarn global add node-gyp \\     # \u0423\u0431\u0438\u0440\u0430\u0435\u043c \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043c\u0443\u0441\u043e\u0440     &amp;&amp; apk del .build-deps &amp;&amp; yarn cache clean &amp;&amp; rm -rf \/usr\/src<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0423\u0436\u0435 \u0437\u0434\u0435\u0441\u044c \u044f \u0431\u043e\u0440\u044e\u0441\u044c \u0437\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u0438\u0437\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u0440\u0430\u0437 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439.<\/p>\n<p>  <\/p>\n<p>\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0442\u0443\u0442: <a href=\"https:\/\/hub.docker.com\/r\/alexxxnf\/spa-builder\">https:\/\/hub.docker.com\/r\/alexxxnf\/spa-builder<\/a>. \u0425\u043e\u0442\u044f \u044f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043d\u0435 \u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0447\u0443\u0436\u0438\u0435 \u043e\u0431\u0440\u0430\u0437\u044b \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0439.<\/p>\n<p>  <\/p>\n<h3 id=\"nginx\">nginx<\/h3>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441\u0442\u0430\u0442\u0438\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 web-\u0441\u0435\u0440\u0432\u0435\u0440. \u042f \u043f\u0440\u0438\u0432\u044b\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 nginx, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<p>  <\/p>\n<p>\u0423 nginx \u0435\u0441\u0442\u044c \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 Docker-\u043e\u0431\u0440\u0430\u0437, \u043e\u0434\u043d\u0430\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441\u0442\u0430\u0442\u0438\u043a\u0438 \u0432 \u043d\u0451\u043c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439. \u041a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0438\u043b\u0438 \u0436\u0435 \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c Dockerfile.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">$ docker run &#8212;rm nginx:1-alpine nginx -V<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">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<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u042f \u0432\u043e\u0437\u044c\u043c\u0443 \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 Dockerfile, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0432 \u043d\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441\u0442\u0430\u0442\u0438\u043a\u0438. \u041c\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u043e HTTPS, \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u0417\u0430\u0442\u043e \u043c\u043e\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0439 \u0444\u0430\u0439\u043b\u044b, \u0441\u0436\u0430\u0442\u044b\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c Brotli, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435, \u0447\u0435\u043c gzip. \u0421\u0436\u0438\u043c\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0430 \u043b\u0435\u0442\u0443 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a\u043e\u0439 Dockerfile \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f. \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u2013 \u043c\u043e\u0438, \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u2013 \u0438\u0437 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0430.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Dockerfile<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\"># \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u0441\u043d\u043e\u0432\u0430 Alpine FROM alpine:3.9 LABEL maintainer=&quot;Aleksey Maydokin &lt;amaydokin@gmail.com&gt;&quot; ENV NGINX_VERSION 1.16.0 ENV NGX_BROTLI_VERSION 0.1.2 ENV BROTLI_VERSION 1.0.7 RUN set -x \\     &amp;&amp; addgroup -S nginx \\     &amp;&amp; adduser -D -S -h \/var\/cache\/nginx -s \/sbin\/nologin -G nginx nginx \\ # \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c nginx \u0438 \u043c\u043e\u0434\u0443\u043b\u044c ngx_brotli \u043a \u043d\u0435\u043c\u0443     &amp;&amp; apk add --no-cache --virtual .build-deps \\             gcc \\             libc-dev \\             make \\             linux-headers \\             curl \\     &amp;&amp; mkdir -p \/usr\/src \\ # \u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438     &amp;&amp; curl -LSs https:\/\/nginx.org\/download\/nginx-$NGINX_VERSION.tar.gz | tar xzf - -C \/usr\/src \\     &amp;&amp; curl -LSs https:\/\/github.com\/eustas\/ngx_brotli\/archive\/v$NGX_BROTLI_VERSION.tar.gz | tar xzf - -C \/usr\/src \\     &amp;&amp; curl -LSs https:\/\/github.com\/google\/brotli\/archive\/v$BROTLI_VERSION.tar.gz | tar xzf - -C \/usr\/src \\     &amp;&amp; rm -rf \/usr\/src\/ngx_brotli-$NGX_BROTLI_VERSION\/deps\/brotli\/ \\     &amp;&amp; ln -s \/usr\/src\/brotli-$BROTLI_VERSION \/usr\/src\/ngx_brotli-$NGX_BROTLI_VERSION\/deps\/brotli \\     &amp;&amp; cd \/usr\/src\/nginx-$NGINX_VERSION \\     &amp;&amp; CNF=&quot;\\             --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 \\     &quot; \\ # \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c     &amp;&amp; .\/configure $CNF \\     &amp;&amp; make -j$(getconf _NPROCESSORS_ONLN) \\     &amp;&amp; make install \\     &amp;&amp; rm -rf \/usr\/src\/ \\ # \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 brotli \u043c\u043e\u0434\u0443\u043b\u044c, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439     &amp;&amp; rm \/usr\/lib\/nginx\/modules\/ngx_http_brotli_filter_module.so \\     &amp;&amp; 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.     &amp;&amp; apk add --no-cache --virtual .gettext gettext \\     &amp;&amp; mv \/usr\/bin\/envsubst \/tmp\/ \\     &amp;&amp; runDeps=&quot;$( \\         scanelf --needed --nobanner \/usr\/sbin\/nginx \/usr\/lib\/nginx\/modules\/*.so \/tmp\/envsubst \\             | awk '{ gsub(\/,\/, &quot;\\nso:&quot;, $2); print &quot;so:&quot; $2 }' \\             | sort -u \\             | xargs -r apk info --installed \\             | sort -u \\     )&quot; \\     &amp;&amp; apk add --no-cache $runDeps \\     &amp;&amp; apk del .build-deps \\     &amp;&amp; apk del .gettext \\     &amp;&amp; mv \/tmp\/envsubst \/usr\/local\/bin\/ \\ # Bring in tzdata so users could set the timezones through the environment # variables     &amp;&amp; apk add --no-cache tzdata \\ # forward request and error logs to docker log collector     &amp;&amp; ln -sf \/dev\/stdout \/var\/log\/nginx\/access.log \\     &amp;&amp; ln -sf \/dev\/stderr \/var\/log\/nginx\/error.log COPY nginx.conf \/etc\/nginx\/nginx.conf EXPOSE 80 STOPSIGNAL SIGTERM CMD [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u042f \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u043f\u043e\u043f\u0440\u0430\u0432\u043b\u044e nginx.conf, \u0447\u0442\u043e\u0431\u044b gzip \u0438 brotli \u0431\u044b\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u0422\u0430\u043a \u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0443 \u043a\u044d\u0448\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u0432\u0435\u0434\u044c \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043c\u0435\u043d\u044f\u044e\u0449\u0430\u044f\u0441\u044f \u0441\u0442\u0430\u0442\u0438\u043a\u0430. \u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0448\u0442\u0440\u0438\u0445\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0430\u0434\u0440\u0435\u0441\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 404 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 index.html, \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0432 SPA.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">nginx.conf<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">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] &quot;$request&quot; '                     '$status $body_bytes_sent &quot;$http_referer&quot; '                     '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';     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 &quot;no-cache, public, must-revalidate, proxy-revalidate&quot;;             }         }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/hub.docker.com\/r\/alexxxnf\/nginx-spa\">https:\/\/hub.docker.com\/r\/alexxxnf\/nginx-spa<\/a>. \u041e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 10,5 \u041c\u0411. \u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 nginx \u0437\u0430\u043d\u0438\u043c\u0430\u043b 19,7 \u041c\u0411. \u041c\u043e\u0439 \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0451\u043d.<\/p>\n<p>  <\/p>\n<h3 id=\"uchim-statiku-ponimat-peremennye-okruzheniya\">\u0423\u0447\u0438\u043c \u0441\u0442\u0430\u0442\u0438\u043a\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0432 SPA \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a\u043e\u0439 RESTful API \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 SPA \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0441\u0431\u043e\u0440\u043a\u0438. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c, \u0442\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u042f \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0445\u043e\u0447\u0443. \u042f \u0445\u043e\u0447\u0443 \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u043e\u0441\u044c \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 CI, \u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u043d\u043e, \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 CD \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0439\u0442\u0438 \u043d\u0430 \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u044c. \u0412 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u0431\u0440\u0430\u0437\u0435 \u044f \u0431\u0443\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435 nginx, \u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 shell-\u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u0442 \u043f\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0437\u0430\u043f\u0438\u0448\u0438\u0442 \u0438\u0445 \u0432 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u043e\u0436\u043c\u0451\u0442 \u0438\u0445 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 nginx.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 Dockerfile \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 ENTRYPOINT. \u041f\u0435\u0440\u0435\u0434\u0430\u0434\u0438\u043c \u0435\u043c\u0443 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 (\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 Angular):<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">docker-entrypoint.sh<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"bash\">#!\/bin\/sh set -e FLAG_FILE=&quot;\/configured&quot; TARGET_DIR=&quot;\/etc\/nginx\/html&quot; replace_vars () {   ENV_VARS=\\'$(awk 'BEGIN{for(v in ENVIRON) print &quot;$&quot;v}')\\'   # \u0412 Angular \u0438\u0449\u0435\u043c \u043f\u043b\u0435\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b \u0432 main-\u0444\u0430\u0439\u043b\u0430\u0445   for f in &quot;$TARGET_DIR&quot;\/main*.js; do     # envsubst \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 \u043f\u043b\u0435\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f     echo &quot;$(envsubst &quot;$ENV_VARS&quot; &lt; &quot;$f&quot;)&quot; &gt; &quot;$f&quot;   done } compress () {   for i in $(find &quot;$TARGET_DIR&quot; | grep -E &quot;\\.css$|\\.html$|\\.js$|\\.svg$|\\.txt$|\\.ttf$&quot;); do     # \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u0441\u0436\u0430\u0442\u0438\u044f     gzip -9kf &quot;$i&quot; &amp;&amp; brotli -fZ &quot;$i&quot;   done } if [ &quot;$1&quot; = 'nginx' ]; then   # \u0424\u043b\u0430\u0433 \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0441\u0430\u043c\u043e\u043c \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435   if [ ! -e &quot;$FLAG_FILE&quot; ]; then     echo &quot;Running init script&quot;     echo &quot;Replacing env vars&quot;     replace_vars     echo &quot;Compressing files&quot;     compress     touch $FLAG_FILE     echo &quot;Done&quot;   fi fi exec &quot;$@&quot;<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0434\u0435\u043b\u0430\u043b \u0441\u0432\u043e\u0451 \u0434\u0435\u043b\u043e, \u0432 js-\u0444\u0430\u0439\u043b\u0430\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430\u0434\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435: <code>${API_URL}<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 SPA \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442 \u043a \u0441\u0432\u043e\u0438\u043c \u0444\u0430\u0439\u043b\u0430\u043c \u0445\u044d\u0448\u0438. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043c\u043e\u0433 \u0441\u043c\u0435\u043b\u043e \u0437\u0430\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0440\u043e\u043a. \u0415\u0441\u043b\u0438 \u0444\u0430\u0439\u043b \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f, \u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f \u0438 \u0435\u0433\u043e \u0445\u044d\u0448, \u0447\u0442\u043e \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u0437\u0430\u043d\u043e\u0432\u043e.<\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432 \u043c\u043e\u0451\u043c \u043c\u0435\u0442\u043e\u0434\u0435, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u0445\u044d\u0448\u0430 \u0444\u0430\u0439\u043b\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438\u043d\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u044d\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0430\u0434\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u0423 \u043c\u0435\u043d\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0435\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0430\u0445.<\/p>\n<p>  <\/p>\n<h3 id=\"sobiraem-finalnyy-obraz\">\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u0440\u0430\u0437<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Dockerfile<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\"># \u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 FROM alexxxnf\/spa-builder as builder # \u0427\u0442\u043e\u0431\u044b \u044d\u0444\u0444\u043a\u0442\u0438\u0432\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u044d\u0448 Docker-\u0430, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 COPY .\/package.json .\/package-lock.json \/app\/ RUN cd \/app &amp;&amp; npm ci --no-audit # \u041f\u043e\u0442\u043e\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 COPY . \/app RUN cd \/app &amp;&amp; npm run build -- --prod --configuration=docker  # \u0412\u0442\u043e\u0440\u043e\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 FROM alexxxnf\/nginx-spa # \u0417\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043c\u043f\u0440\u0435\u0441\u0441\u043e\u0440 COPY --from=builder \/usr\/local\/bin\/brotli \/usr\/local\/bin # \u041f\u043e\u0442\u043e\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0447\u0443\u0434\u043e-\u0441\u043a\u0440\u0438\u043f\u0442 COPY .\/docker\/docker-entrypoint.sh \/docker-entrypoint.sh # \u0418 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 COPY --from=builder \/app\/dist\/app \/etc\/nginx\/html\/ ENTRYPOINT [&quot;\/docker-entrypoint.sh&quot;] CMD [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0434\u0435-\u0443\u0433\u043e\u0434\u043d\u043e.<\/p>\n<\/div><\/div>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/498472\/\"> https:\/\/habr.com\/ru\/post\/498472\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/498472\/\">\n<p>Single-page Application (SPA) \u2013 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 JavaScript \u0438 HTML \u0444\u0430\u0439\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0435\u0448\u0451\u0432\u044b\u0445 \u0438 \u0434\u0430\u0436\u0435 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e GitHub Pages (\u0430 \u0434\u043b\u044f \u043a\u043e\u0433\u043e-\u0442\u043e \u0434\u0430\u0436\u0435 \u0441 narod.ru) \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044f CDN \u0432\u0440\u043e\u0434\u0435 Amazon S3. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<p>  <\/p>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b Docker-\u043e\u0431\u0440\u0430\u0437 \u0441 SPA, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u0430\u043a \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 Kubernetes-\u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435 back-end \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 SPA.<\/p>\n<p>  <\/p>\n<p>\u042f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043e\u0431\u0440\u0430\u0437\u0443:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 (\u043d\u043e \u043d\u0435 \u0432 \u0441\u0431\u043e\u0440\u043a\u0435);<\/li>\n<li>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u043a \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0434\u0438\u0441\u043a\u0430, \u0442\u0430\u043a \u0438 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f RAM;<\/li>\n<li>\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0430\u0445;<\/li>\n<li>\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043b\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b\u043f\u043e\u0442\u0440\u043e\u0448\u0438\u0442\u044c nginx;<\/li>\n<li>\u0441\u043e\u0431\u0440\u0430\u0442\u044c brotli \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432;<\/li>\n<li>\u043d\u0430\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f;<\/li>\n<li>\u043d\u0443 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043a\u0430\u043a \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e Docker-\u043e\u0431\u0440\u0430\u0437.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0426\u0435\u043b\u044c \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043c\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u0438 \u0441\u043f\u0440\u043e\u0432\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u044b\u0442\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u043a\u0440\u0438\u0442\u0438\u043a\u0443.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-302327","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=302327"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302327\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=302327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=302327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=302327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}