Към съдържанието

Настройки за бисквитки

Изберете кои видове бисквитки разрешавате. Можете да промените избора си по всяко време чрез „Настройки за бисквитки“ в долната част на всяка страница. Декларация за поверителност

Необходими

Винаги включени

Нужни са за вход, за запазване на количката и на Вашите избори. Те са винаги включени.

Кои бисквитки?
  • weboke_sessie, weboke_klant, weboke_remember: Вашата сесия и оставането в акаунта
  • weboke_basket: Вашата количка
  • wkBtwIncl: показване на цените с или без ДДС
  • wok_cookies: Вашият избор за бисквитките, 12 месеца

Измерват коя реклама води до посещение или поръчка, за да не плащаме за реклами без резултат.

Кои бисквитки?
  • Google Ads чрез Google Tag Manager (_gcl_au, _gcl_aw), до 90 дни
  • OpenAI Ads, реклами в ChatGPT
  • wok_aff: кой партньор Ви е препратил към нас (партньорска програма), 60 дни

4,6

Държава и език

Всяка държава има собствен сайт, с цените и ДДС на тази държава.

Преглед

Docker compose и защитната стена

Модул 9: Docker и docker compose · Време за четене: 12 минути

Цел на урока: След този урок ще можете да описвате услуги в compose файл, да ги стартирате, обновявате и спирате, и ще можете да обясните защо публикуваните портове на Docker заобикалят ufw и как да предотвратите това.

Основни понятия: compose.yaml, services, image, ports, volumes, environment, .env, restart, networks, depends_on, healthcheck, docker compose up -d, pull, logs, down, отпаднало version:, Docker и ufw, DOCKER-USER, публикуване на 127.0.0.1, тайни, docker.sock

Защо compose?

С docker run (урок 9.2) стартирате един контейнер с дълъг ред опции. Едно истинско приложение обаче често се състои от няколко контейнера: програма, база данни, reverse proxy. Ако трябва да помните тези редове и да ги въвеждате отново след рестарт или актуализация, рано или късно ще сгрешите.

Docker Compose описва всички контейнери на едно приложение в един файл: compose.yaml. Поставяте този файл в отделна папка, например /srv/status/compose.yaml, и управлявате всичко с docker compose. Файлът е едновременно и Вашата документация: какво работи, кой image, кои портове, къде се намират данните. Включете тази папка в резервното си копие (урок 8.1) и ще можете да възстановите приложението на нов сървър за няколко минути.

Плъгинът се казва docker compose (с интервал, версия 2). Старата самостоятелна програма docker-compose (с тире) е заменена; все още я срещате в стари ръководства. Полето version: "3.8" в началото на старите файлове също е отпаднало: Compose винаги използва най-новата схема и при version: показва само предупреждение.

Четене на compose файл

Пример с програма и база данни PostgreSQL:

# /srv/notities/compose.yaml
services:
  app:
    image: ghcr.io/example/notities:1.4
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:8080"
    environment:
      DB_HOST: db
      DB_USER: notities
      DB_PASSWORD: ${DB_PASSWORD}
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_USER: notities
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U notities"]
      interval: 10s
      retries: 5

volumes:
  db-data:

Стъпка по стъпка:

  • services: всяка услуга става контейнер. Името (app, db) е и името на хоста, по което контейнерите се намират един друг. Compose създава отделна мрежа за приложението, така че app се свързва с базата данни на db:5432.
  • image: винаги с таг за версия (урок 9.1).
  • restart: какво прави Docker, когато контейнерът спре или сървърът се рестартира. unless-stopped го стартира отново, освен ако Вие съзнателно не сте го спрели. Без политика за restart Вашето приложение няма да се върне след рестарт (урок 4.2).
  • ports: само приложението публикува порт, и то само на 127.0.0.1. Базата данни не публикува нищо: приложението я достига през вътрешната мрежа. База данни с ports: - "5432:5432" е една от най-честите грешки (вижте по-долу).
  • environment: настройки за програмата. Паролата не е записана буквално, а като ${DB_PASSWORD}.
  • volumes: именуваният volume db-data запазва базата данни, когато контейнерът бъде заменен.
  • depends_on с healthcheck: приложението стартира едва когато базата данни е наистина готова, а не просто стартирана.

Тайни във файл .env

Compose чете променливи като ${DB_PASSWORD} от файл .env в същата папка:

# /srv/notities/.env
DB_PASSWORD=Kies-hier-een-lang-willekeurig-wachtwoord
anna@web1:/srv/notities$ sudo chmod 600 .env

Така паролата не стои в compose файла, който може би съхранявате в Git или поставяте във форум, за да поискате помощ. Добавете .env в .gitignore. Създайте паролата с мениджър на пароли или с openssl rand -base64 24.

Ежедневна употреба

Всички команди изпълнявате в папката с compose файла:

anna@web1:/srv/notities$ sudo docker compose config     # проверка на файла, с попълнени променливи
anna@web1:/srv/notities$ sudo docker compose up -d      # стартиране на всичко (или обновяване спрямо файла)
anna@web1:/srv/notities$ sudo docker compose ps         # състояние за всяка услуга
anna@web1:/srv/notities$ sudo docker compose logs -f app
anna@web1:/srv/notities$ sudo docker compose pull       # изтегляне на новите images
anna@web1:/srv/notities$ sudo docker compose up -d      # замяна на контейнерите с новите images
anna@web1:/srv/notities$ sudo docker compose down       # спиране и премахване на контейнерите

down оставя Вашите volumes. down -v изтрива и volumes на приложението, а с тях и Вашата база данни. Въвеждайте това само ако наистина искате да започнете отначало.

docker compose config е еквивалентът на nginx -t и sshd -t: показва как Compose разбира Вашия файл, с попълнени всички променливи, преди да стартирате каквото и да е. Внимавайте да не поставяте този изход никъде, защото паролите са в него.

Docker заобикаля ufw

Сега най-важният въпрос за сигурността в този модул. В урок 5.2 настроихте ufw на "отказ на всичко, освен SSH, 80 и 443". Бихте очаквали контейнер с ports: - "5432:5432" тогава да е недостъпен. Това не е така.

Документацията на Docker го казва дословно: Docker и ufw използват правилата на защитната стена по начин, който не е съвместим помежду си. Когато публикувате порт, Docker сам добавя правила в защитната стена на ядрото. Тези правила пренасочват трафика към контейнера (транслация на адреси, DNAT), преди да се приложат правилата на ufw. Пакетът значи заобикаля ufw. ufw status не показва нищо особено, докато портът е достъпен от целия интернет. Същото важи и за firewalld.

Освен това Docker без адрес публикува на 0.0.0.0 и [::], т.е. едновременно по IPv4 и IPv6 (урок 9.1).

Три начина да го направите правилно, от простия към сложния:

  1. Не публикувайте нищо, което не трябва да е публично. Бази данни, кешове и вътрешни услуги не получават ports:. Контейнерите в едно и също compose приложение се достигат един друг през вътрешната мрежа.
  2. Публикувайте на loopback. "127.0.0.1:8081:8080". Тогава достъп има само самият сървър, а пред него поставяте reverse proxy (nginx или Caddy, модул 7), който слуша на 443. Docker може да получи това и като стандарт: настройка на daemon кара всички публикувани портове без адрес да попадат на 127.0.0.1.
  3. Правила във веригата DOCKER-USER. Docker създава празна верига DOCKER-USER, която се обхожда преди неговите собствени правила. Там можете сами да добавите правила, например "само този IP адрес има достъп до публикуваните портове". Това е работа за напреднали с iptables или nftables и лесно може да се сбърка. За повечето малки сървъри 1 и 2 са достатъчни.

Винаги проверявайте отвън, както в урок 5.1: nc -vz -w 3 <ip> 5432 от Вашия лаптоп или чрез проверката от курса в задача Z5.1 и Z10.4.

Още две неща, които не правите

  • Не монтирайте /var/run/docker.sock в контейнер, освен ако не знаете точно защо. Контейнер с достъп до Docker сокета може сам да стартира контейнери, включително такъв с целия диск на хоста (урок 9.2). Някои помощни програми (табла за управление, автоматични обновители) го изискват; на практика това означава да дадете root на тази програма.
  • Не използвайте privileged: true или network_mode: host само защото така пише в някое ръководство. И двете в голяма степен премахват изолацията на контейнера. Използвайте ги само ако създателят обяснява защо е необходимо.

Обобщение

  • Compose файлът (compose.yaml) описва всички контейнери на едно приложение; той е и документация и трябва да е в резервното Ви копие.
  • Използвайте тагове за версия, политика за restart, именувани volumes, healthcheck, където е възможно, и тайни в .env с права 600.
  • docker compose config, up -d, ps, logs, pull, down; down -v изтрива и volumes.
  • Публикуваните портове заобикалят ufw и firewalld. Публикувайте само това, което трябва да е публично, а всичко друго на 127.0.0.1 с reverse proxy пред него.
  • Без docker.sock, privileged или network_mode: host без основателна причина.

Тест (quiz)

1. ufw е настроен на "отказ на всичко освен 22, 80 и 443". Вашият compose файл има при базата данни ports: - "5432:5432". Достъпна ли е базата данни от интернет?



2. Как контейнерът app достига базата данни в същото compose приложение, ако базата данни не публикува порт?



3. След рестарт на сървъра контейнерите Ви вече не работят. Какво най-вероятно липсва в compose файла?



4. Каква е разликата между docker compose down и docker compose down -v?



5. Програма за табло за управление изисква в ръководството си - /var/run/docker.sock:/var/run/docker.sock. Какво означава това за сигурността?



Задача

Задача Z9.3: Проверка на compose файл. В примерния файл compose-nakijken.txt се намира (като текстов файл) compose файлът на малък онлайн магазин с приложение, база данни, кеш и инструмент за администриране. В него има шест грешки, разгледани в този урок или в уроци 9.1 и 9.2. За всеки номериран блок от редове посочете дали е правилен или грешен и при всяка грешка изберете правилната корекция. Програмата сравнява с фиксиран ключ. Ако имате собствен compose файл, след това го прегледайте по същите точки.

Задача Z9.3: Проверка на compose файл

Файл към тази задача: compose-nakijken.txt





















Това, което въвеждате, и резултатите от проверката не се съхраняват. Браузърът Ви запомня отговорите и дали сте изпълнили задачата. Ако сте влезли, запазваме само дали задачата е била (почти) правилна в Моите курсове; и там можете да го изтриете.

Още за четене

Моля, изчакайте…

Настройте домейните си

За всеки домейн настройте сървърите за имена, връзката с хостинга и кой ще бъде собственикът.

Домейните Ви се зареждат…