Sign inSign up

uchiru/spa-base

By uchiru

•Updated over 2 years ago

Image
1

100K+

uchiru/spa-base repository overview

⁠SPA base

Docker Repository on Quay

Базовый докер-образ для js SPA.

  • nginx отдает статику из /var/www
  • при запуске статика синхронизируется с s3-бакетом
  • если какой-то js или css не найден, запрос проксируется в s3-бакет
  • при запуске в js,css и html-файлах подменяются шаблоны из переменных окружения. Подробности ниже.

⁠CONFIG

Переменные окружения:

  • BASE_PATH - обязательная - путь, на котором расположен SPA, слеш вначале нужен, в конце - нет.
  • APP_NAME - обязательная - имя приложения, как в шамане
  • S3_ID - обязательная - id к бакету для ассетов
  • S3_KEY - обязательная - key к бакету для ассетов
  • S3_BUCKET - обязательная - название бакета для ассетов
  • CUSTOM_CONFIG_PATH - опциональная - путь до файла, содержимое которого будет включено внутрь директивы server. Подробнее⁠
  • MANDATORY_VARIABLES — опциональная (пока) — список названий переменных через \n, без наличия которых контейнер не стартует.
ENV MANDATORY_VARIABLES="
STUDENT_HEADER_PATH
JWT_AUTH_PATH
"

Пояснения:

У нас SPA обычно живут на каком-то подпути домена, например, uchi.ru/profile/students. В этом случае BASE_PATH=/profile/students. Этот же путь должен быть указан при компиляции ассетов, чтобы (условный) реакт знал, что js и css-чанки лежат тоже не на голом домене.

APP_NAME - нужен в основном чтобы сделать в бакете с ассетами свою директорию и не перемешивать ассеты разных приложений и одного и того же приложения на стейдже и в проде.

⁠Использование

Сам по себе образ не используется, его нужно добавить как базовый образ для статики, так:

# Dockerfile
FROM node:10.15 as build

... BUILD STEPS ...

FROM spa-base
COPY --from=build /app/build /var/www

Затем

docker build -t app .
docker run --name app -it --rm -p 8080:80 \
         -e BASE_PATH=/profile/students \
         -e S3_ID=some \
         -e S3_KEY=some \
         -e S3_BUCKET=uchiru-static-files -e APP_NAME=test-1 app <команда>

Команда:

  • serve - по умолчанию - запускает nginx с root = /var/www
  • upload - загрузить ассеты в бакет, используется в pre-шаге
  • serve-debug - запускает nginx в режиме отладки
⁠Шаблоны в js/css/html/json-файлах

При запуске содержимое js/css/html/json файлов прогоняется через простой шаблонизатор envsub⁠, который заменяет некоторые строки на содержимое соответствующих переменных окружения, например:

  • В файле есть строка <%CLICKSTREAM_URL%>, при наличии такой переменной окружения, будет подставлено ее значение
  • В файле есть строка <%CLICKSTREAM_URL%>, переменной окружения нет, замены не будет, строка так и останется с шаблоном
  • В файле есть строка <%CLICKSTREAM_URL-%>, переменной окружения нет, шаблон заменится на пустую строку
  • В файле есть строка <%CLICKSTREAM_URL-default%>, переменной окружения нет, шаблон заменится на строку default
⁠Закрытие сервиса от старых браузеров

Если ваш сервис не поддерживает какие то версии браузеров, логично его от них закрыть и пользователям вывести вежливое сообщение. Для этого необходимо добавить browserslist.sh в корневую директорию проекта (рядом с entrypoint.sh) и добавить соответсвующую команду для копирования в Dockerfile. В browserslist.sh необходимо указать переменные OUTDATED (список полностью неподдерживаемых браузеров) и NEED_UPDATE (список браузеров требующих обновления). Переменные в browserslist.sh опциональны (как и файл browserslist.sh) и должны быть в формате квери строки для browserslist⁠. Пользователи с браузерами в списке OUTDATED будут направляться на блокирующую страницу https://uchi.ru/lp/old-browser⁠. Пользователи с браузерами в списке NEED_UPDATE будут направляться на информационную страницу https://uchi.ru/lp/old-browser?back_url=https://uchi.ru/parents⁠, где back_url= страница с которой произошел редирект пользователя. При попадании на информационную страницу пользователь получит куку “old_browser_lover” на 1 месяц, по которой можно будет его отловить и повторно не отправлять на информационную страницу. browserslist определяет iOS Safari по версии iOS и если например указать в квери ios_saf <= 10.1 то пользователям с iOS более старых версии (без обновления до новой верии iOS) доступ будет закрыт и если iOS устройство не поддерживает обновление до нужной версии, то пользователь не сможет получить доступ.

Пример Dockerfile:

COPY ./browserslist.sh /browserslist.sh

Пример browserslist.sh:

export OUTDATED="
  Chrome <= 58,
  Firefox <= 57,
  Edge <=16,
  Safari <= 10.1,
  ie <= 11,
  ios_saf <= 10.1,
  Opera <= 44"
export NEED_UPDATE="
  Chrome <= 72,
  Firefox <= 68,
  ios_saf <= 11.1.2,
  Edge <=79,
  Safari <= 11.1.2,
  Opera <= 59"
⁠Дополнительная настройка nginx

В большинстве случаев дополнительная настройка nginx не требуется

⁠Кастомный конфиг

В исключительных случаях можно добавить в приложение файл с доп. настройкой nginx. Его содержимое будет включено внутри директивы server. Путь к файлу нужно указать в переменной окружения CUSTOM_CONFIG_PATH

Пример:

# nginx-custom.conf

location ^~ /foo/(one|two)/bar/ {
  rewrite ^/foo/(one|two)/(.*)$ /foo/$2;
}

В Dockerfile:

# Dockerfile
# после строчки FROM spa-base
COPY nginx-custom.conf /var/nginx/
ENV CUSTOM_CONFIG_PATH=/var/nginx/nginx-custom.conf
⁠SSI

Что бы включить обработку SSI инструкций⁠ в nginx нужно установить переменную окружения USE_SSI, например в Dockerfile:

ENV USE_SSI=true

Важно: получать данные через инструкцию include virtual можно только внутренние location. Например, что бы подключить страницу uchi.ru/stub нужно будет добавить прокси location в кастомный конфиг:

# nginx-custom.conf

location /include-stub {
    internal; # не нужно делать такие location доступными для просмотра извне
    proxy_pass uchi.ru/stub;
}
⁠Безопасность
⁠Content Security Policy

Для того, чтобы nginx по рутовому /%BASE_PATH локейшену начал отвечать хедером Content-Security-Policy необходимо добавить в Dockerfile вашего проекта одну из переменных окружения:

ENV CSP_HEADER "script-src 'self';"
ENV CSP_HEADER_PATH "/app/csp-header" # этот путь указывает на файл в финальном докер-образе (в котором лежит nginx)
ENV CSP_REPORT_ONLY true # в этом случае CSP включается в режиме report only

Tag summary

Content type

Image

Digest

sha256:0c228a0a6…

Size

49.6 MB

Last updated

over 2 years ago

docker pull uchiru/spa-base:dev-support-custom-buckets-ff19f16