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:
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:
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