Docker mufananidzo wekugovera yeSingle Peji Chikumbiro

Single-peji Chishandiso (SPA) seti yeakamira JavaScript uye HTML mafaera, pamwe nemifananidzo nezvimwe zviwanikwa. Nekuti haashanduke zvine simba, kuaburitsa online kuri nyore. Kune huwandu hukuru hwekuchipa uye kunyange emahara masevhisi eizvi, kutanga neGitHub Mapeji akareruka (uye kune vamwe kunyange ne narod.ru) uye kupera neCDN seAmazon S3. Zvisinei, ndaida chimwe chinhu.

Ini ndaida mufananidzo weDocker neSPA kuti ugone kutangwa zviri nyore mukugadzira sechikamu cheKubernetes cluster, uye pamushini wemugadziri wekupedzisira asingazive kuti SPA chii.

Ini ndakazvisarudzira zvinotevera mufananidzo zvinodiwa kwandiri:

  • nyore kushandisa (asi kwete gungano);
  • saizi shoma zvese maererano ne diski uye RAM;
  • configuration kuburikidza nemamiriro ezvinhu akasiyana-siyana kuitira kuti chifananidzo chigone kushandiswa munzvimbo dzakasiyana-siyana;
  • kugovera kwakanyanya kwemafaira.

Nhasi ndichakuudza sei:

  • gut nginx;
  • kuvaka brotli kubva kune zvinyorwa;
  • dzidzisa static mafaera kuti anzwisise nharaunda dzakasiyana;
  • uye zvechokwadi nzira yekuunganidza mufananidzo weDocker kubva pane zvese izvi.

Chinangwa chechinyorwa chino ndechekugovana ruzivo rwangu uye kumutsa nhengo dzenharaunda dzine ruzivo kuti dzishoropodze zvinovaka.

Kugadzira mufananidzo wekugadzira

Kuti uite iyo yekupedzisira Docker mufananidzo mudiki muhukuru, iwe unofanirwa kutevedzera kune miviri mitemo: hushoma hwematanho uye minimalistic base mufananidzo. Imwe yemifananidzo diki yepasi ndeyeAlpine Linux mufananidzo, saka ndizvo zvandichasarudza. Vamwe vangakakavara kuti Alpine haina kukodzera kugadzirwa, uye vangave vakarurama. Asi ini pachangu handina kumbobvira ndaita dambudziko naye uye hapana kupokana naye.

Kuti ndive nezvikamu zvishoma, ini ndichaunganidza chifananidzo mumatanho maviri. Yekutanga dhizaini; zvese zvekubatsira uye mafaera enguva pfupi acharamba ari mairi. Uye muchikamu chekupedzisira ini ndinongonyora pasi yekupedzisira vhezheni yekushandisa.

Ngatitange nemufananidzo wekubatsira.

Kuti ukwanise kuunganidza SPA application, kazhinji unoda node.js. Ini ndichatora iyo yepamutemo mufananidzo, iyo inouyawo nenpm uye yarn package mamaneja. Ini pachangu, ini ndichawedzera node-gyp, inodiwa kuvaka mamwe npm mapakeji, uye iyo Brotli compressor kubva kuGoogle, iyo ichave inobatsira kwatiri gare gare.

Dockerfile ine makomendi.

# Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·
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

Ndatove pano ini ndiri kurwira minimalism, saka chifananidzo chinoiswa pamwe chete neboka guru.

Mufananidzo wapera unogona kuwanikwa pano: https://hub.docker.com/r/alexxxnf/spa-builder. Kunyangwe ini ndichikurudzira kusavimba nemifananidzo yevamwe uye kuunganidza yako.

nginx

Iwe unogona kushandisa chero web server kugovera static content. Ini ndajaira kushanda ne nginx, saka ndichaishandisa izvozvi.

Nginx ine yepamutemo Docker mufananidzo, asi ine yakawandisa mamodule ekugovera nyore static kugovera. Ndeipi iyo inosanganisirwa mukutumira inogona kuonwa nechikwata chakakosha kana mune yepamutemo 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

Ini ndichashandisa iyo Dockerfile sehwaro, asi ini ndichasiya mairi chete izvo zvinodiwa kugovera static zvemukati. Shanduro yangu haizokwanise kushanda pamusoro peHTTPS, haitsigire mvumo, nezvimwe zvakawanda. Asi vhezheni yangu ichakwanisa kugovera mafaera akamanikidzwa neBrotli algorithm, iyo inoshanda zvishoma pane gzip. Tichamanikidza mafaera kamwe chete; hapana chikonzero chekuita izvi panhunzi.

Iyi ndiyo Dockerfile yandakapedzisira nayo. Mhinduro muRussia ndedzangu, muChirungu - kubva kune yekutanga.

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;"]

Ini ndichakurumidza kugadzirisa nginx.conf kuitira kuti gzip nebrotli zvigoneswe nekusingaperi. Ini zvakare ndichasanganisira caching misoro, nekuti isu hatizombofa takachinja static. Uye kubata kwekupedzisira kuchave kwekutungamira zvese zvikumbiro makumi mana nemana kune index.html, izvi zvinodiwa pakufambisa muSPA.

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";
            }
        }
    }
}

Unogona kudhawunirodha mufananidzo wapera pano: https://hub.docker.com/r/alexxxnf/nginx-spa. Zvinotora kusvika 10,5 MB. Iyo yepakutanga nginx yakatora 19,7 MB. Zvandinofarira zvemitambo zvagutsikana.

Kudzidzisa statics kuti unzwisise zvakatipoteredza zvakasiyana

Sei zvigadziriso zvingadikanwa muSPA? Semuenzaniso, kuti utaure kuti ndeipi RESTful API yekushandisa. Kazhinji, marongero enzvimbo inodiwa anoendeswa kuSPA padanho rekuvaka. Kana iwe uchida kushandura chimwe chinhu, iwe uchafanirwa kuvakazve application. handizvidi. Ini ndinoda kuti application ivakwe kamwe chete padanho reCI, uye igadziriswe zvakanyanya sezvinodiwa padanho reCD uchishandisa nharaunda dzakasiyana.

Ehe, static mafaera pachawo haanzwisise chero shanduko yenzvimbo. Naizvozvo, iwe unozofanirwa kushandisa zano. Mumufananidzo wekupedzisira, ini handisi kuzovhura nginx, asi yakakosha shell script iyo inoverenga nharaunda zvinosiyana, zvinyore kune static mafaera, zvimanikidzire, uye chete ipapo kuendesa kutonga kune nginx.

Nechinangwa ichi, iyo Dockerfile inopa iyo ENTRYPOINT paramende. Ngatimupei anotevera script (tichishandisa Angular semuenzaniso):

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 "$@"

Kuti script iite basa rayo, zvigadziriso zvinofanirwa kunyorwa mumafaira ejs mune iyi fomu: ${API_URL}.

Izvo zvakakosha kucherechedza kuti mazhinji emazuva ano maSPA anowedzera hashes kumafaira avo pakuvaka. Izvi zvinodikanwa kuitira kuti browser inogona kuchengetedza faira kwenguva yakareba. Kana iyo faira ikachinja, ipapo hashi yayo ichachinja, iyo inozomanikidza browser kurodha faira zvakare.

Nehurombo, mune yangu nzira, kushandura dhizaini kuburikidza neyakasiyana siyana haitungamiri kune shanduko mufaira hashi, zvinoreva kuti bhurawuza cache inofanirwa kuvharwa neimwe nzira. Ini handina dambudziko iri nekuti masisitimu akasiyana anoiswa munzvimbo dzakasiyana.

Kubatanidza mufananidzo wekupedzisira

Pakupedzisira.

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;"]

Iye zvino mufananidzo unoguma unogona kuunganidzwa uye kushandiswa chero kupi zvako.

Source: www.habr.com