Sawirka Docker ee qaybinta Codsiga Bog Keliya

Codsiga Hal-bog ah (SPA) waa jaangooyo JavaScript ah iyo faylal HTML ah, iyo sidoo kale sawirro iyo agabyo kale. Sababtoo ah si firfircoon isuma beddelaan, ku daabicida internetka aad bay u fududahay. Waxaa jira tiro badan oo ah adeegyo raqiis ah iyo xitaa bilaash ah tan, laga bilaabo GitHub Bogagga fudud (iyo qaar xitaa leh narod.ru) oo ku dhammaanaya CDN sida Amazon S3. Si kastaba ha ahaatee, waxaan u baahanahay wax kale.

Waxaan u baahday sawir Docker ah oo leh SPA si ay si fudud ugu bilaabi karto labadaba wax soo saarka iyada oo qayb ka ah kooxda Kubernetes, iyo mashiinka horumariyaha dambe ee aan wax fikrad ah ka lahayn waxa SPA ay tahay.

Waxaan go'aamiyay shuruudaha sawirka soo socda ee nafteyda:

  • sahlan isticmaalka (laakiin ma aha shirka);
  • cabbirka ugu yar labadaba marka loo eego diskka iyo RAM;
  • qaabeynta iyada oo loo marayo doorsoomayaasha deegaanka si sawirka loogu isticmaali karo deegaanno kala duwan;
  • qaybinta faylasha ugu hufan.

Maanta waxaan kuu sheegi doonaa sida:

  • mindhicirka nginx;
  • ka dhis brotli ilo;
  • baro faylalka taagan si ay u fahmaan doorsoomayaasha deegaanka;
  • iyo dabcan sida loo ururiyo sawirka Docker ee waxaas oo dhan.

Ujeedada maqaalkani waa in aan la wadaago waayo-aragnimadayda iyo kicinta xubnaha bulshada ee khibradda leh dhaleecayn wax dhisaysa.

Dhisidda sawirka isu imaatinka

Si aad u sameyso sawirka ugu dambeeya ee Docker oo yar oo cabbir ah, waxaad u baahan tahay inaad raacdo laba xeer: ugu yaraan lakabyo iyo sawirka hoose ee ugu yar. Mid ka mid ah sawirada saldhigga ugu yar waa sawirka Alpine Linux, markaa taasi waa waxa aan dooran doono. Qaar ayaa laga yaabaa inay ku doodaan in Alpine aysan ku habboonayn wax soo saarka, oo laga yaabo inay sax yihiin. Laakin shaqsi ahaan waligey wax dhibaato ah kalama kulmin isaga, mana jiraan wax dood ah oo ka dhan ah isaga.

Si aan u yeesho lakabyo yar, waxaan ku soo ururin doonaa sawirka 2 marxaladood. Midda kowaad waa qabyo; dhammaan agabka kaalmeeya iyo faylasha ku meel gaadhka ah ayaa ku sii jiri doona. Marxaladda ugu dambeysana waxaan qori doonaa oo keliya nooca ugu dambeeya ee codsiga.

Aan ku bilowno sawirka kaaliyaha.

Si aad u ururiso codsiga HBS, waxaad inta badan u baahan tahay node.js. Waxaan qaadan doonaa sawirka rasmiga ah, kaas oo sidoo kale la socda npm iyo maareeyayaasha xirmada yarn. Anigoo ku hadlaya magacayga, waxaan ku dari doonaa node-gyp, kaas oo loo baahan yahay si loo dhiso qaar ka mid ah xirmooyinka npm, iyo Brotli compressor ka Google, kaas oo anaga anfaca hadhow.

Dockerfile oo leh faallooyin

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

Horeba halkan waxaan u dagaalamayaa minimalism, sidaas darteed sawirka waxaa isku daraya hal koox oo weyn.

Sawirka la dhammeeyey waxaa laga heli karaa halkan: https://hub.docker.com/r/alexxxnf/spa-builder. Inkasta oo aan ku talinayo in aanad ku tiirsanayn sawirada dadka kale oo aad urursato kaaga.

nginx

Waxaad isticmaali kartaa server-ka kasta si aad u qaybiso nuxurka taagan. Waxaan la qabsaday la shaqeynta nginx, markaa hadda waan isticmaali doonaa.

Nginx waxay leedahay sawir Docker oo rasmi ah, laakiin waxay leedahay qaybo aad u badan oo loogu talagalay qaybinta joogtada ah ee fudud. Kuwee lagu daray gaarsiinta waxaa arki kara koox gaar ah ama Dockerfile-ka rasmiga ah.

$ 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

Waxaan u isticmaali doonaa Dockerfile saldhig ahaan, laakiin waxaan uga tagi doonaa kaliya waxa loo baahan yahay si loo qaybiyo nuxurka taagan. Noocaygu ma awoodi doono inuu ka shaqeeyo HTTPS, ma taageeri doono ogolaanshaha, iyo wax ka badan. Laakiin noocaygu wuxuu awood u yeelan doonaa inuu qaybiyo faylalka lagu cadaadiyo Brotli algorithm, kaas oo waxyar ka waxtar badan gzip. Waxaan isku cadaadin doonaa faylalka hal mar, looma baahna in tan lagu sameeyo duulaanka.

Kani waa Dockerfile-kii aan ku dambeeyay. Faallooyinka Ruushku anigaa iska leh, Ingiriisi - oo ka yimid asalka.

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

Isla markiiba waxaan hagaajin doonaa nginx.conf si gzip iyo brotli ay u noqdaan kuwo si toos ah u shaqeeya. Waxa kale oo aan ku dari doonaa caching headers, sababtoo ah waligood isbeddel ma samayn doono. Taabashada kama dambaysta ah waxay noqon doontaa in dhammaan codsiyada 404 lagu wareejiyo index.html, tani waxay lagama maarmaan u tahay socodka HBS.

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

Waxaad ka soo dejisan kartaa sawirka dhammeeyey halkan: https://hub.docker.com/r/alexxxnf/nginx-spa. Waxay qaadataa 10,5 MB. Nginx-kii asalka ahaa wuxuu qaatay 19,7 MB. Xiisaha isboorti waa ku qancay.

Barista statics si ay u fahmaan doorsoomayaasha deegaanka

Maxaa looga baahan karaa dejinta HBS? Tusaale ahaan, si loo cayimo API RESTful ee la isticmaalayo. Caadi ahaan, dejinta jawiga la rabo waxaa loo wareejiyaa HBS marxaladda dhismaha. Haddii aad u baahan tahay inaad wax bedesho, waa inaad dib u dhistaa codsiga. ma rabo Waxaan rabaa in codsiga la dhiso hal mar marxaladda CI, oo la habeeyo inta loo baahan yahay marxaladda CD-ga iyadoo la adeegsanayo doorsoomayaasha deegaanka.

Dabcan, feylasha static laftoodu ma fahmaan doorsoomayaasha deegaanka. Sidaa darteed, waxaad u baahan doontaa inaad isticmaasho qalab. Sawirka kama dambaysta ah, ma bilaabi doono nginx, laakiin qoraal qolof ah oo gaar ah oo akhrin doona doorsoomayaasha deegaanka, u qori doona faylalka taagan, ku cadaadi, ka dibna kaliya u wareejin doona xakamaynta nginx.

Ujeedadan awgeed, Dockerfile-ku wuxuu bixiyaa cabbirka ENTRYPOINT. Aan siino qoraalkan soo socda (iyadoo la adeegsanayo Angular tusaale ahaan):

docker-enterpoint.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 "$@"

Si qoraalku u qabsado shaqadiisa, dejinta waa in lagu qoraa faylasha js ee foomkan: ${API_URL}.

Waxaa xusid mudan in badi HBS-yada casriga ahi ay ku daraan xashiish faylalkooda marka la dhisayo. Tani waa lagama maarmaan si browserku uu si badbaado leh u kaydiyo faylka muddo dheer. Haddii feylku isbeddelo, markaas xashiishkiisu wuu beddeli doonaa, taas oo markaa ku qasbi doonta browserka inuu soo dejiyo faylka mar kale.

Nasiib darro, habkayga, beddelidda qaabeynta iyada oo loo marayo doorsoomayaasha deegaanka ma horseedayso isbeddel ku yimaada xashiishka faylka, taas oo macnaheedu yahay in khasnad browserka ay tahay in si kale loo buriyo. Ma qabo dhibaatadan sababtoo ah habayn kala duwan ayaa la geeyaa deegaan kala duwan.

Isku dhafka sawirka ugu dambeeya

Ugu dambeyntii.

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

Hadda sawirka ka soo baxay waa la soo ururin karaa oo loo isticmaali karaa meel kasta.

Source: www.habr.com