Docker, Kubernetes и Compose: Изграждане на WordPress мулти-сайт екосистема

Docker, Kubernetes и Compose: Изграждане на WordPress мулти-сайт екосистема

В съвременния дигитален свят управлението на множество WordPress сайтове може да се превърне в истинско предизвикателство. Представете си, че трябва да поддържате три различни проекта – блог, онлайн магазин и корпоративен сайт. Всеки има различни нужди, различни версии на плъгини и теми. Традиционният подход би означавал три отделни хостинг акаунта, три комплекта за поддръжка и много главоболия.

Тук на помощ идва Docker – технология, която променя правилата на играта. Заедно с Docker Compose и потенциала на Kubernetes, можем да създадем елегантна екосистема за управление на множество WordPress сайтове. Всичко това – от един централизиран панел.

Защо Docker и контейнеризацията са бъдещето

Docker работи като виртуален контейнер, който опакова вашето приложение заедно с всички необходими зависимости. Помислете за него като за преносима кутия, която можете да отворите навсякъде и всичко вътре да работи перфектно. Няма значение дали сте на Windows, Linux или macOS – вашият WordPress ще функционира еднакво.

Основните предимства на контейнеризацията включват изолация между приложенията, лесно мащабиране и възможност за бързо възстановяване. Всеки сайт живее в собствения си свят, но всички споделят общите ресурси на сървъра по най-ефективния начин.

Docker Compose: Оркестриране на комплексни системи

Docker Compose ни позволява да дефинираме цяла екосистема от контейнери чрез един прост YAML файл. Вместо да стартираме всеки контейнер поотделно, описваме цялата архитектура и я стартираме с една команда.

Ето как изглежда практическа конфигурация за три WordPress сайта с отделни бази данни:

version: '3.8'

networks:
  monitoring-net:
    name: monitoring-net
    external: false

services:
  # WordPress site1
  wordpress-site1:
    image: wordpress:latest
    container_name: site1
    restart: always
    ports:
      - "0.0.0.0:${SITE1_PORT}:80"
    environment:
      WORDPRESS_DB_HOST: site1db
      WORDPRESS_DB_USER: ${SITE1_USER}
      WORDPRESS_DB_PASSWORD: ${SITE1_PASSWORD}
      WORDPRESS_DB_NAME: ${SITE1_DB}
    volumes:
      - ./wordpress-site1:/var/www/html/wp-content
    networks:
      - monitoring-net
    depends_on:
      - db-site1

  db-site1:
    image: mariadb:10.6
    container_name: site1db
    restart: always
    environment:
      MYSQL_DATABASE: ${SITE1_DB}
      MYSQL_USER: ${SITE1_USER}
      MYSQL_PASSWORD: ${SITE1_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - ./db-site1:/var/lib/mysql
    networks:
      - monitoring-net

  # WordPress site2
  wordpress-site2:
    image: wordpress:latest
    container_name: site2
    restart: always
    ports:
      - "0.0.0.0:${SITE2_PORT}:80"
    environment:
      WORDPRESS_DB_HOST: site2db
      WORDPRESS_DB_USER: ${SITE2_USER}
      WORDPRESS_DB_PASSWORD: ${SITE2_PASSWORD}
      WORDPRESS_DB_NAME: ${SITE2_DB}
    volumes:
      - ./wordpress-site2:/var/www/html/wp-content
    networks:
      - monitoring-net
    depends_on:
      - db-site2

  db-site2:
    image: mariadb:10.6
    container_name: site2db
    restart: always
    environment:
      MYSQL_DATABASE: ${SITE2_DB}
      MYSQL_USER: ${SITE2_USER}
      MYSQL_PASSWORD: ${SITE2_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - ./db-site2:/var/lib/mysql
    networks:
      - monitoring-net

  # WordPress site3
  wordpress-site3:
    image: wordpress:latest
    container_name: site3
    restart: always
    ports:
      - "0.0.0.0:${SITE3_PORT}:80"
    environment:
      WORDPRESS_DB_HOST: site3db
      WORDPRESS_DB_USER: ${SITE3_USER}
      WORDPRESS_DB_PASSWORD: ${SITE3_PASSWORD}
      WORDPRESS_DB_NAME: ${SITE3_DB}
    volumes:
      - ./wordpress-site3:/var/www/html/wp-content
    networks:
      - monitoring-net
    depends_on:
      - db-site3

  db-site3:
    image: mariadb:10.6
    container_name: site3db
    restart: always
    environment:
      MYSQL_DATABASE: ${SITE3_DB}
      MYSQL_USER: ${SITE3_USER}
      MYSQL_PASSWORD: ${SITE3_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - ./db-site3:/var/lib/mysql
    networks:
      - monitoring-net

  # phpMyAdmin
  phpmyadmin:
    image: phpmyadmin
    container_name: phpmyadmin
    restart: always
    ports:
      - "0.0.0.0:${PHPMYADMIN_PORT}:80"
    environment:
      PMA_ARBITRARY: 1
    networks:
      - monitoring-net
    depends_on:
      - db-site1
      - db-site2
      - db-site3

Тази конфигурация създава три отделни MariaDB инстанции, всяка с собствена база данни и потребител. Всеки WordPress сайт се свързва към своята собствена база данни, което осигурява пълна изолация между проектите.

Ето стъпките и командите за лесно създаване на всичко необходимо:

Създаване на директории:

mkdir -p {wordpress-site1,wordpress-site2,wordpress-site3} {db-site1,db-site2,db-site3}

Създаване на .env файл:

cat > .env << EOL
# WordPress Site 1
SITE1_PORT=8001
SITE1_USER=site1user
SITE1_PASSWORD=$(openssl rand -base64 16)
SITE1_DB=site1db

# WordPress Site 2
SITE2_PORT=8002
SITE2_USER=site2user
SITE2_PASSWORD=$(openssl rand -base64 16)
SITE2_DB=site2db

# WordPress Site 3
SITE3_PORT=8003
SITE3_USER=site3user
SITE3_PASSWORD=$(openssl rand -base64 16)
SITE3_DB=site3db

# MySQL Root Password
MYSQL_ROOT_PASSWORD=$(openssl rand -base64 16)

# phpMyAdmin
PHPMYADMIN_PORT=8080
EOL

Създаване на мрежата:

docker network create monitoring-net

Стартиране на контейнерите:

docker-compose up -d

Разширяване на екосистемата: Добавяне на четвърти сайт

Добавянето на нов сайт към съществуващата екосистема е изключително просто. Ето как можете да създадете отделен docker-compose.yml файл за четвърти сайт.

Създайте директории за новия сайта:

mkdir -p wordpress-site4 db-site4

Docker Compose файл за новия сайт (docker-compose-site4.yml)

version: '3.8'

networks:
  monitoring-net:
    name: monitoring-net
    external: true

services:
  # WordPress site4
  wordpress-site4:
    image: wordpress:latest
    container_name: site4
    restart: always
    ports:
      - "0.0.0.0:${SITE4_PORT}:80"
    environment:
      WORDPRESS_DB_HOST: site4db
      WORDPRESS_DB_USER: ${SITE4_USER}
      WORDPRESS_DB_PASSWORD: ${SITE4_PASSWORD}
      WORDPRESS_DB_NAME: ${SITE4_DB}
    volumes:
      - ./wordpress-site4:/var/www/html/wp-content
    networks:
      - monitoring-net
    depends_on:
      - db-site4

  db-site4:
    image: mariadb:10.6
    container_name: site4db
    restart: always
    environment:
      MYSQL_DATABASE: ${SITE4_DB}
      MYSQL_USER: ${SITE4_USER}
      MYSQL_PASSWORD: ${SITE4_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - ./db-site4:/var/lib/mysql
    networks:
      - monitoring-net

Актуализирайте .env файла

Добавете променливи за четвъртия сайт:

# WordPress Site 4
SITE4_PORT=8004
SITE4_USER=site4user
SITE4_PASSWORD=$(openssl rand -base64 16)
SITE4_DB=site4db

За стартиране на новия сайт използвайте:

docker-compose -f docker-compose-site4.yml up -d

Новият сайт ще има собствена MariaDB инстанция, напълно изолирана от останалите проекти.

Предимства на архитектурата с отделни бази данни

Архитектурата с отделни MariaDB инстанции за всеки сайт предлага значителни ползи в сравнение с една обща база данни. Първо, пълната изолация означава, че проблем в една база данни не може да засегне останалите сайтове. Второ, всеки сайт може да има различни настройки за производителност, оптимизирани за неговите специфични нужди.

Поддръжката също става по-гъвкава – можете да правите бекъп, възстановяване или миграция на отделен сайт без да засягате останалите. При нужда от мащабиране можете да преместите определен сайт на отделен сървър, докато останалите продължават да работят непрекъснато.

Сигурността се подобрява драстично, тъй като компрометирането на един сайт не дава достъп до данните на останалите. Всеки MariaDB контейнер има собствени credentials и изолирани данни.

Kubernetes: Следващото ниво на мащабиране

Docker Compose е фантастично за един сървър. Но какво се случва, когато имаш десетки WordPress сайтове, които трябва да бъдат разпределени върху множество сървъри, да са отказоустойчиви и да се мащабират автоматично при натоварване? Тук Docker Compose не е достатъчен.

Влиза Kubernetes – де факто стандартът за оркестрация на контейнери.

Ако Docker създава контейнерите, а Compose ги управлява на един сървър, то Kubernetes е диригентът на цял оркестър от сървъри (наричан cluster). Той взема решения:

  • На кой сървър да се пусне всеки контейнер?
  • Как да се възстанови контейнер, който неочаквано се срине?
  • Как да увеличи броя на копията на даден контейнер (да го „мащабира“) при висок трафик?
  • Как безопасно да съхранява пароли и конфигурации?

В света на Kubernetes, ние не казваме „пусни този контейнер там“. Вместо това, ние декларираме желаното състояние чрез YAML манифести. Например: „Искам да имам три работещи копия на моя WordPress сайт, свързани към една shared база данни, и да бъдат достъпни чрез този load balancer.“ Kubernetes се грижи цял живот да поддържа това желано състояние, автоматично коригирайки всяко отклонение.

Основни концепции за WordPress в Kubernetes:

  • Pod: Най-малката единица. Обикновено съдържа един контейнер (напр. WordPress) и може да съдържа допълнителни (напр. за кеширане).
  • Deployment: Дефинира как да се създадат и поддържат множество идентични Pod-ове (replicas) за нашия сайт.
  • Service: Обединява група Pod-ове и предоставя стабилна мрежова точка за достъп до тях (например, балансиращ товара между всички WordPress Pod-ове).
  • Ingress: Действа като умен шлюз, който управлява входящия HTTP(S) трафик и го маршрутизира към правилния Service въз основа на името на домейна (напр. site1.mydomain.com отива към Service на сайт 1, site2.mydomain.com към сайт 2). Това е ключът към мулти-сайт екосистемата.
  • Persistent Volume (PV) & Persistent Volume Claim (PVC): Осигуряват постоянно съхранение за данните (медии, бази данни), което оцелява при рестартиране или преместване на контейнерите.

Networking и комуникация между контейнерите

В нашия пример използваме external network наречена monitoring-net. Това позволява на всички контейнери да комуникират помежду си, а също така да се интегрират с външни мониторинг системи като Prometheus или Grafana.

External мрежите са мощен механизъм за свързване на различни Docker Compose стекове. Можете да имате отделен стек за мониторинг, друг за логове и трети за основните приложения – всички свързани чрез обща мрежа.

Сигурност и best practices

При работа с мулти-сайт среда сигурността е от първостепенна важност. Никога не използвайте слаби пароли в production.

Всеки MariaDB контейнер вече има собствен потребител с ограничени права само към съответната база данни. Това значително намалява риска при компрометиране на един от сайтовете, тъй като нападателят няма достъп до данните на останалите проекти.

Заключение: Бъдещето на web development

Docker, Compose и Kubernetes революционизират начина, по който разработваме и управляваме web приложения. Мулти-сайт WordPress екосистемата, която разгледахме, е само началото. Тази архитектура може да се разшири с additional services като Redis за кеширане, Nginx за reverse proxy или CDN интеграция.

Най-важното е да започнете малко и постепенно да разширявате системата. Започнете с basic Docker Compose setup, тествайте го добре и после добавяйте нови функционалности. Всяка стъпка ще ви научи нещо ново и ще ви доближи до създаването на професионална, скалируема web infrastructure.

Технологиите се развиват бързо, но принципите на добрата архитектура остават постоянни. Инвестирането в разбиране на контейнеризацията днес ще ви дава конкурентни предимства в годините напред. Започнете експериментирането още днес – вашите бъдещи проекти ще ви благодарят за това!

Федя Серафиев

Федя Серафиев

е DevOps технологичен ентусиаст с опит в Linux, Docker, Kubernetes и CI/CD. Той споделя практични ръководства и анализи, които помагат на специалистите да изграждат по-добри и ефективни системи. На devopsbg.net Федя предоставя актуални и полезни насоки за автоматизация, сигурност и оптимизация на инфраструктурата.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *


Колко е 6 + 8 ? (въведете числото)