Docker-compose для создания веб-сервера

Обновлено и опубликовано Опубликовано:

Рассмотрим сценарий, который позволит быстро развернуть простой веб-сервер в docker. В качестве компонентов мы будем использовать:

  • Веб сервер NGINX.
  • Интерпретатор сценариев PHP.
  • СУБД MariaDB.
  • Веб-интерфейс для управления базами данный phpMyAdmin.

Помимо этого, мы приведем пример минимальных настроек для работы данного сервера.

Подготовка

Подготовим операционную систему к работе.

1. Установка Docker.

Для запуска сценария нам необходимо установить docker и docker-compose. Для каждого типа Linux необходимо выполнить свой набор команд.

Подробнее процесс описан в инструкции Установка Docker на Linux.

2. Каталог для работы.

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

mkdir /opt/webserver

cd /opt/webserver

Команды ниже будут выполняться из расчета, что мы находимся в созданном каталоге.

Мы готовы к созданию сценария.

Сценарий и настройка сервера

Создаем файл docker-compose:

vi docker-compose.yml

  1. ---
  2.  
  3. services:
  4.  
  5.   web_nginx:
  6.     image: nginx
  7.     hostname: web_nginx
  8.     container_name: web_nginx
  9.     restart: unless-stopped
  10.     environment:
  11.       TZ: "Europe/Moscow"
  12.     ports:
  13.       - 80:80
  14.       - 443:443
  15.     volumes:
  16.       - ./nginx/conf.d:/etc/nginx/conf.d
  17.       - ./nginx/ssl:/etc/nginx/ssl
  18.       - ./www_data:/usr/share/nginx/html
  19.  
  20.   web_php:
  21.     build:
  22.       context: ./php/
  23.       args:
  24.         buildno: 2023101101
  25.     hostname: web_php
  26.     container_name: web_php
  27.     restart: unless-stopped
  28.     user: root
  29.     environment:
  30.       TZ: "Europe/Moscow"
  31.     volumes:
  32.       - ./www_data:/var/www/html
  33.       - ./php/php.ini:/usr/local/etc/php/php.ini
  34.  
  35.   web_db:
  36.     image: mariadb
  37.     hostname: web_db
  38.     container_name: web_db
  39.     restart: unless-stopped
  40.     environment:
  41.       TZ: "Europe/Moscow"
  42.       MARIADB_DATABASE: website
  43.       MARIADB_USER: website
  44.       MARIADB_PASSWORD: website123
  45.       MARIADB_ROOT_PASSWORD: root_password
  46.     volumes:
  47.       - ./mysql_data:/var/lib/mysql
  48.  
  49.   web_pma:
  50.     image: phpmyadmin
  51.     hostname: web_pma
  52.     container_name: web_pma
  53.     restart: unless-stopped
  54.     environment:
  55.       TZ: "Europe/Moscow"
  56.       PMA_HOST: web_db
  57.       UPLOAD_LIMIT: 50M
  58.     ports:
  59.       - 81:80

* сценарий создаст 4 контейнера:

  • web_nginx — веб-сервер, на базе nginx.
  • web_php — интерпретатор PHP.
  • web_db — сервер баз данных MariaDB.
  • web_pma — веб-инструмент для работы с базами данных MySQL/MariaDB.
5 - 18 Создаем контейнер веб-сервера nginx. В качестве образа используем одноименный nginx.
16 Конфигурационные файлы будут находится в каталоге nginx/conf.d хостовой машины (в каталоге с docker-compose.yml) и /etc/nginx/conf.d внутри контейнера.
17 Каталоги для хранения сертификатов.
18 Файлы веб-приложения — www_data на хосте docker и /usr/share/nginx/html внутри контейнера.
20 - 33 Контейнер с PHP. 
21 - 24 Мы не будем брать готовый образ и сами соберем контейнер с использованием Dockerfile. Создание и описание последнего будет ниже в инструкции.
32 Как и для веб-сервера мы используем каталог www_data с рабочими файлами сайта, но пробрасываем их в каталог /var/www/html внутри контейнера.
33 Файл с настройками PHP.
35 - 47 Контейнер с базой данных MariaDB.
42 При инициализации будет создана база с именем website.
43 При инициализации будет создан пользователь с именем website.
44 Пароль пользователя website будет website123.
45 Указываем пароль для суперпользователя root.
49 - 59 Контейнер с phpMyAdmin.
56 С помощью данной переменной окружения говорим, на каком контейнере запущена СУБД.
57 Разрешаем передачу файлов размером не более 50 Мб. По умолчанию ограничение в 2 Мб.
59 Обратите внимание, что данный контейнер мы вешаем на внешний 81 порт.

Создадим каталог для хранения Dockerfile — он нам нужен для сборки контейнера с PHP:

mkdir php

Создадим в данном каталоге файл Dockerfile:

vi php/Dockerfile

  1. FROM php:8.2-fpm
  2.  
  3. MAINTAINER Dmitriy Mosk <master@dmosk.ru>
  4.  
  5. ENV TZ=Europe/Moscow
  6.  
  7. RUN apt update && \
  8.     docker-php-ext-install mysqli

* с помощью данного файла будет собран контейнер с интерпретатором php и компонентом php-fpm, принимающим запросы на обработку скриптов.

1 В качестве базового образа берем php:8.2-fpm. Из его названия видно, что версия php будет 8.2. Меняем на версию, которая нужна, именно, вам.
7 - 8 Дополнительно установим php расширение mysqli. Как правило, для рабочего проекта нужно больше разрешений. Вы можете их перечислить через пробел.

Создадим конфигурационный файл php.ini:

vi php/php.ini

error_reporting =  E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE
short_open_tag = On
post_max_size = 1G
upload_max_filesize = 512M
date.timezone = "Europe/Moscow"

* где:

  • error_reporting — для продуктива лучше не отображать информацию об устаревших функциях (E_DEPRECATED), плохой совместимости кода (E_STRICT) и информации о потенциальных проблемах (E_NOTICE).
  • short_open_tag — позволяет использовать короткую нотацию для раскрытия блока код PHP.
  • post_max_size — максимальный объем данных, которые можно передать на сервер методом POST.
  • upload_max_filesize — максимальный объем загружаемого файла.
  • date.timezone — часовой пояс.

Создаем каталог:

mkdir -p nginx/conf.d

И создаем конфигурационный файл nginx для виртуального домена:

vi nginx/conf.d/dmosk.ru.conf

  1. server {
  2.     listen       80;
  3.     listen       443 ssl;
  4.  
  5.     server_name  dmosk.ru;
  6.  
  7.     location ~ /.well-known {
  8.         root /usr/share/nginx/html;
  9.         allow all;
  10.     }
  11.  
  12.     if ($scheme = 'http') {
  13.         return 301 https://$host$request_uri;
  14.     }
  15.  
  16.     ssl_certificate     /etc/nginx/ssl/dmosk.ru.crt;
  17.     ssl_certificate_key /etc/nginx/ssl/dmosk.ru.key;
  18.  
  19.     root  /usr/share/nginx/html;
  20.  
  21.     error_log /var/log/nginx/error.log;
  22.  
  23.     index index.php;
  24.  
  25.     location / {
  26.         try_files $uri $uri/ index.php;
  27.     }
  28.  
  29.     location ~ \.php$ {
  30.         set $root_path /var/www/html;
  31.         fastcgi_pass web_php:9000;
  32.         fastcgi_index index.php;
  33.         fastcgi_param SCRIPT_FILENAME $root_path$fastcgi_script_name;
  34.         include fastcgi_params;
  35.         fastcgi_param DOCUMENT_ROOT $root_path;
  36.     }
  37.  
  38.     location ~* ^.+\.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
  39.             expires modified +1w;
  40.     }
  41. }

* данный файл описывает поведение и ответ веб-сервера nginx при обращении к домену dmosk.ru.

2 - 3 Сервер будет слушать на портах 80 и 443.
5 Указывает, для какого домена будет действовать данная настройка.
7 - 10 Данная настройка понадобится, если мы захотим получить бесплатный сертификат от Let's Encrypt.
12 - 14 Перенаправляет запросы с http на https.
16 - 17 Пути до файлов сертификатов. Необходимы для работы https.
29 - 36 Данный блок описывает поведение nginx при обработке файлов с расширением php. В нашем примере запросы будут передаваться контейнеру web_php.

Создаем каталог для хранения сертификатов:

mkdir nginx/ssl

Генерируем самоподписанные сертификаты:

openssl req -new -x509 -days 1461 -nodes -out nginx/ssl/dmosk.ru.crt -keyout nginx/ssl/dmosk.ru.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=dmosk.ru/CN=www.dmosk.ru"

* данная команда сформирует ключи dmosk.ru.crt и dmosk.ru.key в каталоге nginx/ssl относительно нашей рабочей папки.

Для тестирования веб-сервера нам будет достаточно самозаверенного сертификата. Но для продуктивной среды лучше будет получить сертификаты от доверенного центра.

Сценарий для развертывания веб-сервера готов.

Запуск и тестирование

Для создания и запуска контейнеров выполняем команду:

docker-compose up -d

Запуск контейнеров займет какой-то время. Ждем.

Создадим файл:

vi www_data/index.php

<?php

phpinfo();

?>

Можно проверить работу сервера из командной строки:

curl -k https://127.0.0.1

Мы должны получить ответ в виде html-страницы с параметрами PHP.

Того же самого эффекта можно добиться в браузере, перейдя по адресу https://<IP-адрес хоста docker>. При получении предупреждения безопасности, игнорируем его.

Сертификат от Let's Encrypt

Ранее мы настроили веб-сервер с самоподписанным сертификатом, но в рабочей среде нам нужен сертификат, которому доверяют многие системы. Проще всего использовать бесплатный сертификат от Let's Encrypt. Для его получения сначала открываем наш файл docker-compose:

vi docker-compose.yml

И добавляем новый volume для контейнера web_nginx:

---
 
services:
 
  web_nginx:
  ...
  volumes:
  ...
    - ./nginx/well-known/:/usr/share/nginx/html

* мы пробрасываем внутрь контейнера каталог nginx/well-known.

Теперь можно запустить команду:

docker run -it --rm --name certbot -v "/opt/webserver/nginx/ssl:/etc/letsencrypt" -v "/opt/webserver/nginx/well-known:/usr/share/nginx/html" certbot/certbot certonly --webroot --agree-tos --email postmaster@dmosk.ru --webroot-path /usr/share/nginx/html/ -d dmosk.ru -d www.dmosk.ru

* данная команда создаст временный контейнер, который запросит сертификат для домена dmosk.ru и его поддомена www.dmosk.ru. В качестве каталога, где будет размещен временный файл проверки будет использоваться /usr/share/nginx/html, который является каталогом /opt/webserver/nginx/well-known на хосте docker и также смотри в папку /usr/share/nginx/html внутри веб-контейнера web_nginx.

Если настройка выполнена верно, мы должны получить файлы сертификата, которые будут находиться в каталоге /opt/webserver/nginx/ssl/live/dmosk.ru. Пропишем новые сертификаты:

vi nginx/conf.d/dmosk.ru.conf

    ssl_certificate     /etc/nginx/ssl/live/dmosk.ru/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/live/dmosk.ru/privkey.pem;

Перечитаем конфигурацию веб-сервером. Сначала проверим ее:

docker exec web_nginx nginx -t

И если ошибок нет:

docker exec web_nginx nginx -s reload

Для продления сертификата используем команду:

docker run -it --rm --name certbot -v "/opt/webserver/nginx/ssl:/etc/letsencrypt" -v "/opt/webserver/nginx/well-known:/usr/share/nginx/html" certbot/certbot renew

Читайте также

Дополнительная информация по работе с docker и веб-серверами:

1. Создание собственного образа Docker.

2. Настройка веб-сервера в Docker (NGINX + PHP + MariaDB).

3. Шпаргалка по работе с docker-compose.

4. Docker-compose для создания nginx entrypoint.

5. NGINX + Apache + MariaDB (MySQL) + PHP + PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на Ubuntu.

6. NGINX + Apache (httpd) + MariaDB (MySQL) + PHP + PHP-FPM (fastCGI) + FTP + PHPMyAdmin + Memcached + Postfix на CentOS 8.

# DevOps # Linux # Виртуализация # Серверы
Дмитрий Моск — частный мастер
Был ли вам полезен этот скрипт?

Да            Нет