Мені зручно щось написати в блозі, просто зайшовши на сервер і створивши та відредагувавши відповідний .md
файл.
Зміни одразу видно, навіть не потрібно оновлювати сторінку в браузері.
Це тому, що в мене Eleventy налаштований у дев-режимі, тобто, команда npx eleventy --serve
запущена прямо в контейнері, а контейнер має відкритий порт 8080
, на який перекидує запити reverse proxy:
browser -> nginx:80 -> eleventy:8080 (npx)
Але стикнувся з проблемою: сторінки́ при кожному переході за посиланням “здригуються”, тобто, спочатку відмальовується сирий html, а потім він перемальовується згідно з правилами css/js.
Ще однією проблемою є те, що старі сторінки не видаляються, а залишаються в теці _site
. І видалити їх може тільки root
, руцями, а не через менеджмент контейнерів.
Очевидно, потрібно робити все правильно: готувати сторінки вдома, а викладати їх на сервер вже у готовому вигляді.
Для вирішення цієї проблеми я скористався multi-stage build, де під час першої стадії сторінки́ готуються, а під час другої — подаються внутрішнім сервером, а не npx
, як це було раніше.
Отже, нова схема така:
browser -> nginx:80 -> eleventy:80 (nginx:80)
Чому всюди 80
? Тому що якщо залишати порт 8080
, то на стадії створення шару з nginx
треба буде заморочитися з тим, щоб nginx
працював на порту 8080
, тоді як на порту 80
він працює з коробки.
Отже, налаштування reverse proxy до :
location / {
proxy_pass http://eleventy:8080;
та після :
location / {
proxy_pass http://eleventy:80;
Налаштування Eleventy Dockerfile
до :
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci && \
npm prune && \
rm -rf /tmp/* /var/tmp/* /usr/local/lib/node_modules/npm/.cache
COPY . .
EXPOSE 8080
CMD ["npx", "eleventy", "--serve"]
та після :
FROM node:22-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci && \
npm prune --production && \
rm -rf /tmp/* /var/tmp/* /usr/local/lib/node_modules/npm/.cache
COPY . .
RUN rm -rf _site && npx @11ty/eleventy
FROM nginx:stable-alpine-slim
COPY --from=builder /app/_site /usr/share/nginx/html
EXPOSE 80
І ще я видалив монтування теки з вихідним кодом з Eleventy docker-compose.yml
:
volumes:
- ./:/app
тому що тепер вихідний код один раз копіюється в образ на першій стадії в Dockerfile
.
Це означає, що після зміни вихідного коду якоїсь сторінки тепер потрібно не просто нічого не робити, не просто оновити сторінку в браузері, не просто перезапустити контейнер, і навіть не просто перепідняти контейнери через docker compose up -d
, а треба перебудувати о́брази:
docker compose up -d --build