Single-page Application (SPA) ndi gulu la mafayilo a JavaScript ndi HTML osasunthika, komanso zithunzi ndi zinthu zina. Chifukwa sasintha kwambiri, kuwasindikiza pa intaneti ndikosavuta. Pali ntchito zambiri zotsika mtengo komanso zaulere pa izi, kuyambira ndi Masamba osavuta a GitHub (ndipo ena ngakhale ndi narod.ru) ndikutha ndi CDN ngati Amazon S3. Komabe, ndinafunikira chinthu china.
Ndinkafuna chithunzi cha Docker chokhala ndi SPA kuti chizikhazikitsidwa mosavuta popanga ngati gawo la gulu la Kubernetes, komanso pamakina a wopanga kumbuyo yemwe sadziwa kuti SPA ndi chiyani.
Ndadzipangira izi:
- kumasuka kugwiritsa ntchito (koma osati kusonkhana);
- kukula kochepa pa disk ndi RAM;
- kasinthidwe kudzera muzosintha zachilengedwe kuti chithunzicho chigwiritsidwe ntchito m'malo osiyanasiyana;
- kugawa bwino kwambiri mafayilo.
Lero ndikuuzani momwe:
- matumbo nginx;
- kumanga brotli kuchokera ku magwero;
- phunzitsani mafayilo osasunthika kuti amvetsetse zosintha zachilengedwe;
- komanso momwe mungasonkhanitsire chithunzi cha Docker kuchokera ku zonsezi.
Cholinga cha nkhaniyi ndikugawana zomwe ndakumana nazo ndikupangitsa anthu odziwa zambiri kuti azidzudzula.
Kupanga chithunzi cha msonkhano
Kuti chithunzi chomaliza cha Docker chikhale chaching'ono, muyenera kutsatira malamulo awiri: magawo ochepa ndi chithunzi chochepa cha minimalistic. Chimodzi mwazithunzi zazing'ono kwambiri ndi chithunzi cha Alpine Linux, ndizomwe ndisankhe. Ena angatsutse kuti Alpine si yoyenera kupanga, ndipo iwo angakhale olondola. Koma panokha, sindinakhalepo ndi vuto lililonse ndi iye ndipo palibe zotsutsana naye.
Kuti ndikhale ndi zigawo zochepa, ndisonkhanitsa chithunzicho mu magawo awiri. Yoyamba ndikulemba; zida zonse zothandizira ndi mafayilo osakhalitsa azikhala momwemo. Ndipo pomaliza ndingolemba zomaliza za pulogalamuyi.
Tiyeni tiyambe ndi chithunzi chothandizira.
Kuti mupange pulogalamu ya SPA, nthawi zambiri mumafunika node.js. Nditenga chithunzi chovomerezeka, chomwe chimabweranso ndi oyang'anira phukusi la npm ndi ulusi. M'malo mwa ine ndekha, ndiwonjezera node-gyp, yomwe ikufunika kuti ipange mapaketi a npm, ndi kompresa ya Brotli yochokera ku Google, yomwe itithandiza mtsogolo.
Dockerfile ndi ndemanga.
# ΠΠ°Π·ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π·
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
Kale pano ndikulimbana ndi minimalism, kotero chithunzicho chimayikidwa pamodzi ndi gulu limodzi lalikulu.
Chithunzi chomalizidwa chikupezeka apa:
nginx
Mutha kugwiritsa ntchito seva iliyonse yapaintaneti kuti mugawire zomwe zili zokhazikika. Ndazolowera kugwira ntchito ndi nginx, ndiye ndizigwiritsa ntchito tsopano.
Nginx ili ndi chithunzi chovomerezeka cha Docker, koma ili ndi ma module ambiri osavuta kugawa. Zomwe zikuphatikizidwa pakubweretsa zitha kuwonedwa ndi gulu lapadera kapena mu Dockerfile yovomerezeka.
$ 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
Ndigwiritsa ntchito Dockerfile ngati maziko, koma ndingosiya zomwe zimafunikira kuti ndigawire zomwe zili zokhazikika. Mtundu wanga sungathe kugwira ntchito pa HTTPS, sugwirizana ndi chilolezo, ndi zina zambiri. Koma mtundu wanga udzatha kugawa mafayilo oponderezedwa ndi algorithm ya Brotli, yomwe ndi yothandiza pang'ono kuposa gzip. Tidzakakamiza mafayilo kamodzi; palibe chifukwa chochitira izi pouluka.
Iyi ndiye Dockerfile yomwe ndidamaliza nayo. Ndemanga mu Russian ndi anga, mu Chingerezi - kuchokera pachiyambi.
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;"]
Ndikonza nthawi yomweyo nginx.conf kuti gzip ndi brotli aziyatsidwa mwachisawawa. Ndiphatikizanso mitu ya caching, chifukwa sitidzasinthanso static. Ndipo kukhudza komaliza kudzakhala kulondolera zopempha zonse za 404 ku index.html, izi ndizofunikira pakuyenda mu SPA.
nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module /usr/lib/nginx/modules/ngx_http_brotli_static_module.so;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip_static on;
brotli_static on;
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root html;
try_files $uri /index.html;
etag on;
expires max;
add_header Cache-Control public;
location = /index.html {
expires 0;
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
}
}
}
Mutha kukopera chithunzi chomalizidwa apa:
Kuphunzitsa ma statics kuti mumvetsetse zosintha zachilengedwe
Chifukwa chiyani makonda angafunike mu SPA? Mwachitsanzo, kuti mufotokozere RESTful API yoti mugwiritse ntchito. Nthawi zambiri, makonda a malo omwe mukufuna amasamutsidwa ku SPA pomanga. Ngati mukufuna kusintha china chake, muyenera kumanganso pulogalamuyo. sindikuzifuna. Ndikufuna kuti pulogalamuyo imangidwe kamodzi pagawo la CI, ndikukonzedwa momwe zingafunikire pagawo la CD pogwiritsa ntchito zosintha zachilengedwe.
Zachidziwikire, mafayilo osasunthika okha samamvetsetsa zosintha zilizonse zachilengedwe. Chifukwa chake, muyenera kugwiritsa ntchito chinyengo. Pachithunzi chomaliza, sindidzayambitsa nginx, koma chipolopolo chapadera chomwe chidzawerenge kusintha kwa chilengedwe, kuwalembera ku mafayilo osasunthika, kuwapanikiza, ndiyeno tumizani ku nginx.
Pachifukwa ichi, Dockerfile imapereka gawo la ENTRYPOINT. Tiyeni timupatse zotsatirazi (pogwiritsa ntchito Angular monga chitsanzo):
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 igwire ntchito yake, zoikamo ziyenera kulembedwa m'mafayilo a js mu fomu iyi:${API_URL}
.Ndizofunikira kudziwa kuti ma SPA amakono amawonjezera ma hashes pamafayilo awo pomanga. Izi ndizofunikira kuti osatsegula athe kusunga fayiloyo kwa nthawi yayitali. Ngati fayilo isintha, ndiye kuti hashi yake idzasintha, zomwe zidzakakamiza osatsegula kutsitsanso fayiloyo.
Tsoka ilo, mu njira yanga, kusintha kasinthidwe kudzera muzosintha zachilengedwe sikubweretsa kusintha kwa fayilo hashi, zomwe zikutanthauza kuti cache ya msakatuli iyenera kukhala yosavomerezeka mwanjira ina. Ndilibe vuto ili chifukwa masinthidwe osiyanasiyana amayikidwa m'malo osiyanasiyana.
Kuyika pamodzi chithunzi chomaliza
Pomaliza.
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;"]
Tsopano chithunzi chotsatira chikhoza kusonkhanitsidwa ndikugwiritsidwa ntchito kulikonse.
Source: www.habr.com