Некоторое время назад я писал статью про быстрое разворачивание окружения под WordPress, а так же саму установку CMS. В ней был акцент на разработку, поэтому не было простого способа запустить сайт сразу на https. Я решил пойти дальше и полностью автоматизировать установку wordpress в docker с https, чтобы можно было сразу развернуть на vps и показать в рабочем варианте. Пришлось немного доработать предыдущий вариант, добавив туда контейнер с nginx и let's encrypt.
Введение
Сразу скажу, что мной двигала лень самостоятельной настройки всего этого хозяйства. В связи с этим я искал готовые контейнеры, которым можно было бы доверять и не заботиться об их обновлении и поддержке. На долю секунды у меня возникла мысль собрать контейнеры самостоятельно, но я ее быстро отбросил :) Тогда мне было бы проще и быстрее настраивать все без докера банальным башем или ансиблом.
Для самого web сервера под wordpress нет проблем, так как docker контейнер предоставляет сама wordpress. А вот с let's encrypt возникли некоторые затруднения. Чего-то простого и легковесного не попадалось. В итоге остановился вот на этом проекте - https://docs.linuxserver.io/general/swag. Это многофункциональный web сервер, который больше заточен на проксирование запросов. Я сначала хотел использовать только его в том числе и в качестве веб сервера, но в итоге решил все же остаться на стандартном контейнере от wordpress.
Проект linuxserver достаточно известный. У них много готовых контейнеров на все случаи жизни, так что решил остановиться на нем. Немного поковырялся внутри, посмотрел, как все устроено. Когда разобрался, начал реализацию изначальной идеи - автоматизировать установку wordpress через docker сразу по https с бесплатными сертификатами от let's encrypt. Запускать все буду через docker-compose. Если у вас еще не установлен докер и композ к нему, используйте мою статью - установка docker на centos.
Подготовка конфигов
В начале подготовим конфиг nginx для проксирования запросов из контейнера с swag в wordpress. Назовем его nginx-default, так как он будет заменять дефолтный конфиг nginx.
server { listen 80; listen [::]:80; server_name 253197.simplecloud.ru; return 301 https://$host$request_uri; } server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; root /var/www/html/example; index index.html index.htm index.php; server_name 253197.simplecloud.ru; include /config/nginx/proxy-confs/*.subfolder.conf; include /config/nginx/ssl.conf; client_max_body_size 64M; location / { try_files $uri $uri/ /index.php?$args @app; } location @app { proxy_pass http://wordpress; proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Real-IP $remote_addr; } }
Вам нужно будет в нем заменить только имя сервера - 253197.simplecloud.ru. Это dns запись vds на simplecloud, которые я обычно использую для теста. Мало того, что есть возможность почасовой аренды, так сразу же с виртуалкой идет прописанное dns имя. В итоге такие vds очень удобно использовать для тестов и временного размещения чего-либо. Рекомендую.
Далее я подготовил конфиг configure-wp.sh для установки и первоначальной настройки wordpress с помощью инструмента wp-cli, который запускается в отдельном контейнере. После того, как он все выполнит, завершает свою работу.
retries=0 while : do if wp core install --url="253197.simplecloud.ru" --title="test blog" --admin_user="admin" --admin_password="pass" --admin_email="admin@sample.com" then break else retries=$((retries+1)) echo "Couldn't connect to DB. Try - ${retries}. Sleeping 5 seconds and will retry ..." sleep 5 fi if [ "${retries}" -eq "30" ] then echo "Couldn't connect to DB 30 times. Exiting." exit 1 fi done wp theme install donovan --activate wp theme uninstall twentynineteen wp theme uninstall twentyseventeen wp theme uninstall twentytwenty wp plugin install wordpress-importer --activate #wp plugin install classic-editor --activate #wp plugin install wp-mail-smtp --activate #wp plugin install cyr3lat --activate #wp plugin install wordpress-seo --activate wp plugin uninstall akismet wp plugin uninstall hello wp language core install ru_RU --activate
Здесь надо не забыть поменять имя сайта, а так же указать учетную запись для администратора, его email.
Так же я отдельно подготовил файл .htaccess с конфигурацией веб сервера apache, который используется в контейнере wordpress.
# BEGIN WordPress RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] # END WordPress php_value memory_limit 256M php_value upload_max_filesize 64M php_value post_max_size 64M php_value max_execution_time 300 php_value max_input_time 1000
Подготовка окончена, можно переходить к непосредственно установке wordpress через docker.
Запуск wordpress в docker с https
Теперь самое главное - готовим конфиг docker-compose для нашей магии, с помощью которой wordpress будет автоматически установлен одной командой. И не придется заморачиваться с сертификатами и всем остальным. Это все отлично подойдет для разработчиков. Самые отважные так запускают сайты в прод заказчикам. В целом, криминала в этом нет, но мне кажется на мелких проектах и одиночных vps лучше все это без докера в прод выпускать.
Вот мой финальный docker-compose.yaml.
version: '3' services: swag: image: linuxserver/swag container_name: swag cap_add: - NET_ADMIN environment: - TZ=Europe/Moscow - URL=253197.simplecloud.ru # - SUBDOMAINS=www, - VALIDATION=http volumes: - "./nginx-default:/config/nginx/site-confs/default" ports: - 443:443 - 80:80 restart: unless-stopped mysql: image: mysql:8 container_name: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: wordpress volumes: - "./mysql:/var/lib/mysql" wordpress: image: wordpress:php7.4-apache container_name: wordpress depends_on: - mysql environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: root WORDPRESS_DB_NAME: wordpress volumes: - "./html:/var/www/html/" - "./.htaccess:/var/www/html/.htaccess" wp-cli: image: wordpress:cli container_name: wp-cli user: "33:33" environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: root WORDPRESS_DB_NAME: wordpress volumes: - "./html:/var/www/html/" - "./configure-wp.sh:/opt/configure-wp.sh" command: "bash /opt/configure-wp.sh"
Жирным я выделил то, что вам нужно заменить на свои значения. Сохраняем конфиг и запускаем docker-compose:
# docker-compose up
Наблюдаем в консоли запуск нашего проекта на wordpress с помощью docker контейнеров. Если все в порядке, то последним вы должны у видеть примерно следующее.
Успешный выпуск tls сертификата lert's encrypt будет выглядеть в логах вот так.
Можно сходить по адресу сайта и убедиться, что все работает.
Ваша рабочая директория со скриптами и исходниками будет выглядеть следующим образом.
- html - исходники сайта
- mysql - бинарные файлы базы данных
Можете все это забэкапить или положить в git, настроив исключение для директории с базой. Ее можно дампить отдельно и как-то сохранять. При желании можно в тот же git класть, если она не очень большая.
Бэкап wordpress в docker
Отдельно расскажу, как такой сайт бэкапить или куда-то переносить. Первым делом надо сделать дамп базы данных, которая живет в docker. У меня была отдельная заметка на этот счет - Backup mysql базы в docker контейнере. В нашем случае получается такая команда:
# docker exec mysql /usr/bin/mysqldump -u root --password=root wordpress | gzip -c > ~/`date +%Y-%m-%d`_wordpress.sql.gz
Исходники сайта будут лежать в директории html. Таким образом, для бэкапа всего сайта вам достаточно куда-то скопировать исходники и дамп с базой. Я рекомендую для этого использовать rsync. У меня есть отдельная статья по этой теме - настройка бэкапа с помощью rsync.
Видео
Заключение
Вот так современные технологии упрощают и ускоряют разработку и обслуживание. Сравните с тем, что надо сделать, чтобы настроить типовой веб сервер вручную - настройка веб сервера apache. А тут раз, два и все готово. И потом переносится на любую ОС с докером за минуту. Другое дело, что чтобы во всем этом разбираться, надо сначала научиться вручную все это настраивать, а потом переходить к контейнерам. Иначе они будут как черный ящик. Когда что-то сломается, останется только потыкать в него, но это не приведет к решению проблемы.
Другой вариант решения вопроса - автоматизировать все это с помощью ansible. Я пробовал что-то делать в этом направлении, но реально написать хороший плейбук занимает много времени. Если работаешь не на однотипном потоке, это не оправдывает затраты времени. С докером быстрее и проще получается.
Онлайн курс по Kubernetes
Онлайн-курс по Kubernetes – для разработчиков, администраторов, технических лидеров, которые хотят изучить современную платформу для микросервисов Kubernetes. Самый полный русскоязычный курс по очень востребованным и хорошо оплачиваемым навыкам. Курс не для новичков – нужно пройти вступительный тест.Если вы ответите "да" хотя бы на один вопрос, то это ваш курс:
- устали тратить время на автоматизацию?
- хотите единообразные окружения?;
- хотите развиваться и использовать современные инструменты?
- небезразлична надежность инфраструктуры?
- приходится масштабировать инфраструктуру под растущие потребности бизнеса?
- хотите освободить продуктовые команды от части задач администрирования и автоматизации и сфокусировать их на развитии продукта?
Владимир а есть пример этого стека для большого количество сайтов (к примеру больше 20).
1) Как в таком случае лучше организовать структуру сайтов.
2) Как ограничить память и cpu для контейнеров?
3) Как рассчитать лучше сколько ресурсов необходимо для 20/50 сайтов?
4) Один стек/контейнер для баз хватит или лучше делать для каждого сайта свой контейнер? Тоже самое если к примеру подключить redis cache, хвтает одного контейнера?
5) Насколько удобно отправить логи каждого контейнера в ELK стек?
6) Какой load balancer смотреть?
Стоит в таком случае смотреть на ansible? Или docker-compose проще? Или вообще не стоит делать это через doker? :)
Заранее спасибо
Для такого количества сайтов нужен совершенно другой подход. Тут все надо планировать в зависимости от рабочего процесса. Опять же, речь про dev или prod сервер идет? Для прода там и логи, и мониторинг и ресурсы, все надо планировать и строить под конкретные задачи и потребности.
Речь про prod сервер. Последние 15 лет пользовался в основном 3-мя контрольными панелями: ISP Manager, VestaCP, Plex со своими серверами. Последние 2 удобные и позволяют в принципе все делать, но время потраченное на настройку и все остальное увеличивается ( ну к примеру если надо перенести 10 доменов на новый сервер, делаешь по одному и настройки то тут, то там и все это занимает время ). Щас появились еще 2 сервера и хотелось попробовать что-то новое, docker и контейнеры и была мысль что это лучшее и проще настраивать, также все в месте + используя правильно шаблоны можно одновременно добавить логи, мониторинг везде где нужно.
В вашем случае нужна автоматизация, а docker сам по себе ее не дает. С ним настроек не меньше, а еще больше будет, если все делать вручную. А автоматизировать судя по всему у вас некому. Если сайты типовые, я бы их не в докер переносил на один общий веб сервер (nginx + php-fpm), а настраивал добавление новых сайтов через какую-то автоматизация, например ansible. Или на худой конец bash.
Тем лучше что эти значения никто не затрет, это не будет зависеть от настроек сервера, можно т будет в каталог сайта поросто целиком все файлы cms закидывать не парясь каждый раз с правой этого файлика.
Это пример для композа
volumes:
- ./lc-php.ini:/usr/local/etc/php/conf.d/php.ini
Файлик lc-php.in рядом с докер композ файлом внутри можно писать своим memory_limit = 256M и так далее.
Это на самом деле на любителя. Я работаю с разработчиками и вижу, что они чаще всего через .htaccess что-то меняют. Им так проще, понятнее, удобнее. Хотя сам я всегда параметры php сервера правлю и .htaccess вообще не использую, чтобы не привязываться к apache. Но с wordpress отдельная история. Его официальный образ для docker на apache. Плюс, я лично много раз сталкивался с тем, что не на apache у wordpress что-то глючит. Например, Elementor не работает на некоторых страницах. Так что в экосистеме wordpress .htaccess очень актуален.
Так потому и не работает что так мне надо делать, ну ок
В чем же тогда преимущества Dockera, если по вашим словам "Когда что-то сломается, останется только потыкать в него, но это не приведет к решению проблемы.". В 90% как раз что-то случается и админы ищут для себя варианты, которые как раз устойчивы к разным поломкам и так далее... Но в целом статья хорошая. На днях буду пробовать запускать докер.
Преимущество, очевидно, в скорости настройки всего этого добра. Черным ящиком это будет для тех, кто не разбирается, как это внутри устроено. Например, для меня это не будет проблемой, так как я понимаю и работу докера и внутренности контейнера. Я быстро решу проблему. Посыл был в том, что мало научиться запускать что-то с помощью докера, надо еще разобраться, как это все устроено и работает.
Вместо того чтоб .htaccess хакать лучше php.ini в доуере поменять
А чем лучше? Тут проще и быстрее. И настройки все под рукой.