# Запуск WordPress в Docker Compose

WordPress — одна из самых популярных CMS в мире. Порядка 40% всех сайтов в сети используют WordPress.

И это легко объяснить: WordPress лёгок и прост в обращении, для него выпущено множество плагинов и визуальных тем, для работы с ним не нужны глубокие знания о работе в сети. WordPress одинаково успешно справляется как с созданием небольших локальных блогов, так и с большими новостными сайтами.

Единственной проблемой WordPress можно назвать установку. Для полноценной установки WordPress на сервер требуется установка программного стека LAMP или LEMP (Nginx в качестве веб-сервера), а это может занять определённое время. Именно поэтому некоторые хостинговые компании предлагают готовые решения в виде серверов с предустановленными популярными CMS (opens new window).

Для того, чтобы ускорить и упростить процесс самостоятельной установки WordPress на сервер, мы предлагаем инструкцию по запуску WordPress с помощью Docker Compose.

# Что такое Docker Compose

Docker Compose это — удобный и функциональный инструмент, входящий в состав Docker. Его используют, чтобы развернуть целый проект, а не отдельно взятое приложение. Например, если необходимо создать сайт, который будет использовать базу данных для аутентификации пользователей.

Docker Compose позволяет создавать несколько контейнеров, связанных в одну внутреннюю сеть, и управлять ими как единым целым. А все параметры развёртывания уже готовой внутренней сети и контейнеры с необходимыми образами указываются в одном файле.

В этой инструкции мы воспользуемся Docker Compose для запуска сайта на CMS WordPress: запустим Nginx, MySQL и WordPress в отдельных контейнерах, объединим их в единую внутреннюю сеть и проверим работоспособность нашего проекта.

Для начала работы нам потребуется настроенный сервер с Ubuntu, предустановленные Docker и Docker Compose, а также зарегистрированный домен, к которому мы привяжем наш сайт.

# Настройка параметров веб-сервера

Сначала создадим директорию, в которой будет находиться наш проект, и перейдём в неё:

mkdir wordpress
cd wordpress

Внутри этой директории создадим папку для конфигурационного файла веб-сервера:

mkdir nginx-conf

Создадим сам конфигурационный файл, в котором укажем основные параметры работы: имя нашего сервера, порт, на котором будет работать веб-сервер, блок обработки PHP и запросов статичных активов.

Мы будем создавать текстовые файлы с помощью редактора vim, но вы можете использовать другой редактор, например, nano.

Для серверов на Джино можно также воспользоваться файловым менеджером, чтобы создавать вложенные папки и файлы:

vim nginx-conf/nginx.conf

Содержимое конфигурационного файла должно быть следующим:

server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }

        location = /favicon.ico {
                log_not_found off; access_log off;
        }
        location = /robots.txt {
                log_not_found off; access_log off; allow all;
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}

Здесь:

  • listen — указывает Nginx слушать порт 80.

  • server_name — имя нашего сервера. В этой строке нужно указать доменное имя, к которому вы хотите привязать свои сайты.

  • index — порядок обработки индексных файлов. Здесь мы указываем на первом месте php-файл, чтобы он первым обрабатывал запросы.

  • root — имя корневой директории для запросов к нашему серверу. Эта директория используется как точка монтирования в момент сборки.

  • location ~ /.well-known/acme-challenge — это блок расположения, который будет обрабатывать запросы в директории .well-known.

  • location / — здесь мы используем директиву try_files для проверки файлов, соответствующих отдельным запросам URI. Вместо страницы с ошибкой 404 мы будем передавать контроль файлу index.php.

  • location ~.php$ — этот блок будет обрабатывать PHP-запросы и проксировать их в наш контейнер для WordPress. Также здесь мы добавим параметры конфигурации, принадлежащие протоколу FastCGI.

  • location ~ /.ht — обрабатывает файлы .htaccess, поскольку Nginx не будет их обслуживать. В данном случае deny_all гарантирует, что файлы .htaccess никогда не будут отображаться для пользователей.

  • location = /favicon.ico, location = /robots.txt — эти блоки гарантируют, что запросы для /favicon.ico и /robots.txt не будут регистрироваться.

  • location ~\ (css|gif|ico|jpeg|jpg|js|png)$ — отключает запись в журнал для запросов статичных активов и обеспечивает высокую кэшируемость этих запросов, поскольку обычно их трудно обслуживать.

Сохраняем наш файл и переходим к созданию переменных среды, которые будут передаваться в контейнеры приложений и базы данных.

# Создание переменных среды

В процессе работы нашей базе данных и WordPress понадобится доступ к некоторым переменным среды. Эти переменные содержат как чувствительную информацию (root-пароль к базе данных, имя и пароль администратора базы данных), так и нечувствительную (имя базы данных и её хост).

Вместо того чтобы прописывать эти переменные в нашем docker-compose-файле, мы создадим отдельный .env-файл и запретим его копирование. Это позволит нам указывать все чувствительные переменные в одном месте и быть уверенными, что они не копируются и не перемещаются без нашего контроля.

Находясь в директории нашего проекта (~/wordpress), создадим файл, в котором будут храниться чувствительные переменные среды:

vim .env

В новом файле укажем значения наших переменных:

MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password

Чтобы избежать копирования нашего файла, укажем его в .gitignore и .dockerignore — файлах, указывающих на то, какие файлы нельзя копировать при создании git-репозиториев (если вы собираетесь использовать git в качестве системы контроля версий) и docker-образов.

Если вы планируете работать с Git, инициируйте текущую директорию в качестве репозитория:

git init

Теперь откройте .gitignore-файл:

vim .gitignore

Укажите здесь файл, содержащий чувствительные переменные среды:

.env

То же самое нужно сделать для docker:

vim .dockerignore

В этом файле укажем не только наш файл с чувствительными переменными, но и все файлы, которые с ним связаны:

.env
.gitignore
docker-compose.yml
.dockerignore

Сохраним и закроем наш файл.

Наша чувствительная информация защищена, и можно перейти непосредственно к созданию docker-compose-файла.

# Создание файла docker-compose

Файл docker-compose.yml определяет, какие службы будут запущены в вашем проекте. Службы — это отдельные контейнеры с приложениями, образы которых скачиваются непосредственно после запуска compose-файла.

В Docker Compose можно запустить несколько контейнеров с разными приложениями, объединить их в единую внутреннюю сеть и указать на использование одних и тех же томов.

В нашем случае мы создадим отдельные контейнеры для WordPress, Nginx и MySQL.

Создадим docker-compose.yml:

vim docker-compose.yml

Начнём с общей информации о файле и определим первую службу — MySQL:

version: '3'

services:
  db:
    image: mysql:8.0
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes:
      - dbdata:/var/lib/mysql
    command: '--default-authentication-plugin=mysql_native_password'
    networks:
      - app-network

Чтобы было понятнее, что мы делаем и зачем, приведём пояснения, описывающие содержимое каждого отдельного блока:

  • version — версия compose-файла, соответствующая текущей версии Docker.

  • image — образ приложения, которое будем использовать. В данном случае мы указываем конкретное значение (8.0), чтобы избежать возможных проблем при появлении более новой версии (параметр latest).

  • container_name — имя контейнера, в котором будет запускаться наше приложение.

  • restart — устанавливает политику перезапуска контейнера. Обычно указывают «no», но мы укажем «unless-stopped», т.е контейнер будет перезапускаться, пока не будет остановлен вручную.

  • env_file — указание файла, в котором содержатся переменные среды.

  • environment — добавляем дополнительные переменные среды, в нашем случае это имя нашей базы данных. Поскольку это нечувствительная переменная, её можно указать прямо в compose-файле.

  • volumes — создаём том dbdata в директории /var/lib/mysql. Это стандартная директория для баз данных.

  • command — определение метода аутентификации для PHP и WordPress. Поскольку эти приложения не будут поддерживать стандартный метод аутентификации, то здесь мы вручную определяем значение для default-authentication-plugin, равное значению переменной среды mysql_native_password.

  • networks — указание на то, что наш контейнер db будет подключён к app-network — внутренней сети, которую мы определим в самом конце нашего файла.

После определения службы баз данных определяем службу WordPress. В том же файле docker-compose.yml после строки network в блоке для баз данных вставляем пустую строку и пишем следующий блок текста:

  wordpress:
    depends_on:
      - db
    image: wordpress:5.1.1-fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - wordpress:/var/www/html
    networks:
      - app-network

Здесь:

  • depends_on — параметр, который определяет зависимость контейнера «wordpress» от контейнера «db» — «wordpress» не будет запущен, пока не запустится «db».

  • image — образ скачиваемого приложения. В нашем примере мы используем WordPress 5.1.1-fpm-alpine.

  • env_file — здесь мы также указываем наш .env-файл, поскольку именно WordPress будет пользователем базы данных, и для него нужны имя и пароль.

  • environment — в этом блоке переменных среды мы указываем переменные, необходимые для работы WordPress, при этом присваиваем значения из env-файла. Также здесь мы определяем имя хоста (mysql-сервер, запущенный в разделе db и по умолчанию работающий на порте 3306). Имя базы данных для WordPress мы указываем то же, которое указали на предыдущем шаге в разделе db (wordpress).

  • volumes — создаём том «wordpress» в /var/www/html, который является точкой сборки. Используя том таким образом, мы сможем организовать обмен данными между всеми контейнерами в нашем проекте.

  • networks — добавляем наш контейнер в сеть «app-network».

Следующий на очереди — блок веб-сервера. Также вставляем пустую строку после networks в блоке wordpress в уже открытом файле и продолжаем ввод текста:

  webserver:
    depends_on:
      - wordpress
    image: nginx:1.15.12-alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
    networks:
      - app-network

Помимо уже описанных параметров обратим здесь внимание на:

  • ports — здесь указан 80, который отмечен в конфигурационном файле веб-сервера в самом начале нашей инструкции.

  • volumes — здесь мы определяем сразу несколько томов и связей: - wordpress:/var/www/html — это указание поместит код WordPress в /var/www/html, директорию, которую в конфигурации нашего веб-сервера мы указали как root; - ./nginx-conf:/etc/nginx/conf.d — это указание связывает конфигурационный файл веб-сервера на хосте и в контейнере. Таким образом, все изменения в конфигурационном файле на хосте переносятся в файл в контейнере.

Также добавляем наш контейнер в сеть app-network.

Теперь можно переходить к определению томов и внутренней сети нашего проекта. Это будут заключительные блоки нашего docker-compose.yml:

volumes:
  wordpress:
  dbdata:

networks:
  app-network:
    driver: bridge

Здесь:

  • volumes определяет тома,которые будут созданы при работе Docker Compose. Тома расположены по адресу /var/lib/docker/volumes/. Данные из томов могут быть доступны для любого контейнера, расположенного в сети, что позволяет организовать обмен данными между контейнерами.

  • networks: — создаёт внутреннюю сеть, которая обеспечивает связь между контейнерами, при этом для связи с внешней сетью контейнеры используют только порт 80 веб-сервера.

Теперь можно сохранить и закрыть наш compose-файл.

# Запуск Docker-Compose

Находясь в директории нашего проекта (~/wordpress), запустим Docker Compose:

docker-compose up -d

Docker Compose создаст необходимые контейнеры и внутреннюю сеть между ними, скачает указанные образы программного обеспечения и запустит WordPress.

Теперь, чтобы проверить правильность работы нашего проекта, откроем браузер и зайдём по адресу, который мы указывали в качестве доменного имени. Если всё было сделано правильно, откроется окно мастера установки WordPress.