Как правильно задеплоить next js и wordpress с ci/cd из гитхаба?

Ссылка скопирована
1 ответ

Всем привет, я фронт разработчик и мне не хватает кругозора в деплое готовых приложений. Я хочу развернуть пет проект, простенький сайт на нексте в режиме ssr(yarn build и yarn start) и его админкой в виде хедлесс wordpress. При этом я хочу чтобы у сайта было доменное имя нормальное, а вот админку можно повесить на любой домен или поддомен основного. Плюс чтобы разработка шла автоматизировано из репозиториев гитхаба и на мерджи бы, приложения обновлялись. Я так понимаю что мне нужна докеризация. Но по идее для водпресса нужна внешняя база данных, чтобы она не сбрасывалась при обновлении контейнера. В общем я надеюсь понятно что я хочу и понятен мой диллетантсктй уровень в ci/cd. И я так понимаю что мне нужен впс, я выбирал между беготом и Яндекс Клаудом, но я так и не понял почему у них большая разница в цене. Буду благодарен за любую информацию и направление в какую сторону копать и настраивать это все и на чем. Всем добра)

PS также не должно нарушать все наши законы по хранению информацию и всего такого…..
PSPS возможно есть максимально простые и максимально готовые решения для таких как я
PSPSPS на крайний случай я бы развернул вп с тех доменом на обычном хостинге и некст на впс, закинув его через сфтп, и стартанув терминал, но хочется чего-то более технологичного, уверен такие решения есть

Дополнительно:

ВП, конечно, можно использовать как безголовый движок. Но нужно ли это делать.? Скорее нет чем да. Профита никакого, а вот геморроя (в тч и при поддержке) - выше крыши.

  • Тут скорее вопрос как это максимально удобно задеплоить, чем выбор технологий. Каждый лепит пет проекты на чем умеет. Я долго думал что использовать для повседневных сайтов, типа визиток, каталогов и интернет магазинов, в принципе вп подходит. Если уже брать какой-то более сложный и интересный функционал, то уже стоит отдавать работу беку и не брать цмски или хедлесс цмски. А какие могут быть альтернативы?
  • Ответы:

    У меня был опыт работы Next + WP в продакшне. Самый удобный и реиспользуемый подход, который получился опытным путём - это упаковка всего вышеперечисленного в докер контейнеры. Таким образом мы упрощаем деплой примерно в 100 раз (несколько десятков команд против одной docker compose up -d).

    1. Нужно развернуть WP + MySQL+ PHPMyAdmin + MailHog (если есть необходимость тестировать кучу писем локально)

    docker-compose.yml

    version: '3.1'  services:    wp:     container_name: ${NAME}-wordpress     image: wordpress:latest # https://hub.docker.com/_/wordpress/     ports:       - ${IP}:${PORT}:80 # change ip if required     volumes:       - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini #      - ./wp-app:/var/www/html  Full wordpress project #      - ./plugins:/var/www/html/wp-content/plugins       #- ./plugin-name/trunk/:/var/www/html/wp-content/plugins/plugin-name # Plugin development       - ./${REPO_THEME_NAME}:/var/www/html/wp-content/themes/${REPO_THEME_NAME} # Theme development     environment:       WORDPRESS_DB_HOST: db       WORDPRESS_DB_NAME: "${DB_NAME}"       WORDPRESS_DB_USER: root       WORDPRESS_DB_PASSWORD: "${DB_ROOT_PASSWORD}"     depends_on:       - db     links:       - db    pma:     container_name: ${NAME}-phpmyadmin     image: phpmyadmin/phpmyadmin     environment:       # https://docs.phpmyadmin.net/en/latest/setup.html#docker-environment-variables       PMA_HOST: db       PMA_PORT: 3306       MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"       UPLOAD_LIMIT: 50M     ports:       - ${IP}:8080:80     links:       - db:db    db:     container_name: ${NAME}-mysql     image: mysql:latest # https://hub.docker.com/_/mysql/ - or mariadb https://hub.docker.com/_/mariadb     ports:       - ${IP}:3306:3306 # change ip if required     volumes:       - ./wp-data:/docker-entrypoint-initdb.d       - db_data:/var/lib/mysql     environment:       MYSQL_DATABASE: "${DB_NAME}"       MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"    mailhog:     container_name: ${NAME}-mailhog     image: mailhog/mailhog     ports:       - "8025:8025"       - "1025:1025" volumes:   db_data:  networks:   wordpress:     name: wp-wordpress     driver: bridge

    version: '3.1' services: wp: container_name: ${NAME}-wordpress image: wordpress:latest # https://hub.docker.com/_/wordpress/ ports: - ${IP}:${PORT}:80 # change ip if required volumes: - ./config/php.conf.ini:/usr/local/etc/php/conf.d/conf.ini # - ./wp-app:/var/www/html Full wordpress project # - ./plugins:/var/www/html/wp-content/plugins #- ./plugin-name/trunk/:/var/www/html/wp-content/plugins/plugin-name # Plugin development - ./${REPO_THEME_NAME}:/var/www/html/wp-content/themes/${REPO_THEME_NAME} # Theme development environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_NAME: "${DB_NAME}" WORDPRESS_DB_USER: root WORDPRESS_DB_PASSWORD: "${DB_ROOT_PASSWORD}" depends_on: - db links: - db pma: container_name: ${NAME}-phpmyadmin image: phpmyadmin/phpmyadmin environment: # https://docs.phpmyadmin.net/en/latest/setup.html#docker-environment-variables PMA_HOST: db PMA_PORT: 3306 MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}" UPLOAD_LIMIT: 50M ports: - ${IP}:8080:80 links: - db:db db: container_name: ${NAME}-mysql image: mysql:latest # https://hub.docker.com/_/mysql/ - or mariadb https://hub.docker.com/_/mariadb ports: - ${IP}:3306:3306 # change ip if required volumes: - ./wp-data:/docker-entrypoint-initdb.d - db_data:/var/lib/mysql environment: MYSQL_DATABASE: "${DB_NAME}" MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}" mailhog: container_name: ${NAME}-mailhog image: mailhog/mailhog ports: - "8025:8025" - "1025:1025" volumes: db_data: networks: wordpress: name: wp-wordpress driver: bridge

    .env

    REPO_THEME_NAME=nov-dom NAME=NOVDOM IP=127.0.0.1 PORT=80 DB_ROOT_PASSWORD=password DB_NAME=wordpress

    REPO_THEME_NAME=nov-dom NAME=NOVDOM IP=127.0.0.1 PORT=80 DB_ROOT_PASSWORD=password DB_NAME=wordpress

    Итак, мы получили работающих сервер с Wordpress. Выше описанный пример мы используем для локальной разработки тем, но его легко адаптировать под любые нужны.
    Важно, чтобы в процессе локальной разработки у тебя не был смонтирован весь Wordpress, в таком случае комп будет обрабатывать перенос всего ядра при каждом сохранении файлов внутрь контейнера. Оставляй только файлы темы, для такой разработки хватит и калькулятора.

    При основном деплое, если будет желание прокинуть какие-то особенные файлы, это делается легко через docker exec и docker cp из локальной машины внутрь виртуалки докера.

    docker-compse файл для Next простой настолько насколько это возможно.

    version: '3' services:   nextjs:     build: ./     ports:     - "8080:3000"

    version: '3' services: nextjs: build: ./ ports: - "8080:3000"

    После остаётся проксировать трафик с портов на определенные роуты.

    Самый простой вариант - накатить на 81 порт машины NGINX Proxy Manager
    Через него в визуальном интерфейсе можно сделать примерно всё что угодно с трафиком без гемороя с конфигами. (Такое простое проксирование уж подавно)

    Docker compose для NPM можно найти на оф.сайте

    version: '3.8' services:   app:     image: 'jc21/nginx-proxy-manager:latest'     restart: unless-stopped     ports:       # These ports are in format <host-port>:<container-port>       - '80:80' # Public HTTP Port       - '443:443' # Public HTTPS Port       - '81:81' # Admin Web Port       # Add any other Stream port you want to expose       # - '21:21' # FTP     environment:       # Mysql/Maria connection parameters:       DB_MYSQL_HOST: "db"       DB_MYSQL_PORT: $DB_MYSQL_PORT       DB_MYSQL_USER: $DB_MYSQL_USER       DB_MYSQL_PASSWORD: $DB_MYSQL_PASSWORD       DB_MYSQL_NAME: $DB_MYSQL_NAME       # Uncomment this if IPv6 is not enabled on your host       DISABLE_IPV6: 'true'     volumes:       - ./data:/data       - ./letsencrypt:/etc/letsencrypt     depends_on:       - db    db:     image: 'jc21/mariadb-aria:latest'     restart: unless-stopped     environment:       MYSQL_ROOT_PASSWORD: $DB_MYSQL_ROOT_PASSWORD       MYSQL_DATABASE: $DB_MYSQL_NAME       MYSQL_USER: $DB_MYSQL_USER       MYSQL_PASSWORD: $DB_MYSQL_PASSWORD     volumes:       - ./mysql:/var/lib/mysql

    version: '3.8' services: app: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: # These ports are in format <host-port>:<container-port> - '80:80' # Public HTTP Port - '443:443' # Public HTTPS Port - '81:81' # Admin Web Port # Add any other Stream port you want to expose # - '21:21' # FTP environment: # Mysql/Maria connection parameters: DB_MYSQL_HOST: "db" DB_MYSQL_PORT: $DB_MYSQL_PORT DB_MYSQL_USER: $DB_MYSQL_USER DB_MYSQL_PASSWORD: $DB_MYSQL_PASSWORD DB_MYSQL_NAME: $DB_MYSQL_NAME # Uncomment this if IPv6 is not enabled on your host DISABLE_IPV6: 'true' volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt depends_on: - db db: image: 'jc21/mariadb-aria:latest' restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: $DB_MYSQL_ROOT_PASSWORD MYSQL_DATABASE: $DB_MYSQL_NAME MYSQL_USER: $DB_MYSQL_USER MYSQL_PASSWORD: $DB_MYSQL_PASSWORD volumes: - ./mysql:/var/lib/mysql

    Конфиги из разных проектов, надо поднять базы на разных портах.

    .env

    DB_MYSQL_PORT=3306 DB_MYSQL_USER=example DB_MYSQL_ROOT_PASSWORD=example DB_MYSQL_PASSWORD=example DB_MYSQL_NAME=example

    DB_MYSQL_PORT=3306 DB_MYSQL_USER=example DB_MYSQL_ROOT_PASSWORD=example DB_MYSQL_PASSWORD=example DB_MYSQL_NAME=example

    ***Всё, что описывается выше, это личный опыт, никого не призываю это брать информацию и считать ее единственной верной. Есть решения лучше и производительнее, но для реализации это проекта, требующие более глубинных знаний

    ***** Думаю с деплоем контейнеров, у тебя проблем не возникнет

    Насчет того, где разворачивать. Пользуюсь Бегетом около 4-х лет, и больше всего меня подкупает, что у них круглосуточная поддержка. Но ценник может кусаться. Качество оборудования, отказоустойчивость, API для получения статистики, есть всё.

    Как альтернативу можешь использовать FirstByte, дешевый и сердитый

    • Спасибо огромное за развернутый ответ. Я правильно понимаю, что могу это все развернуть на одном впс, а не на двух? В докер вп, получается я докидываю файлы в уже развернутый контейнер? А если бы я деплоил из гитхаба, он умеет так делать или только новые контейнеры создает и пушит их? Потому что если новые, то он будет скидывать данные из базы и тогда мне нужна какая-то облачная база данных, или обычный хостинг на том же вордпрессе или кстати по идее, я на самом впс могу поставить базу и уже в нее коннектиться из докера?
    • Алексей Фищук, Постараюсь ответить по порядку.
      1. Когда ты разворачиваешь что-то в докере, по сути ты хранишь свои приложения в отдельных виртуалках. Т.е. когда ты пишешь docker ps, ты как раз видишь свои отдельные линукс контейнеры и в консоль каждого ты можешь попасть через docker exec. Это азы и я как фронтендер искренне советую посидеть недельку на ютюбе и узнать как работает развёртывание через Dockerfile и через docker compose. И то и то используется в зависимости от требований.
      Следовательно, ответ, да, ты можешь развернуть неограниченное количество контейнеров, сколько влезет в твою тачку по производительности. В этом и прелесть.

      2. Если тебе надо, ты всегда можешь открыть консоль своего контейнера и прокинуть любые файлы внутрь через docker exec + docker cp. Но как правило это не часто надо.

      3. Надо понимать с чем мы работаем, контейнеры можно хранить в docker hub (это аналог любого другого хранилища, только для уже собранных контейнеров). Но этим можно принебречь. Я бы тебе советовал написать 1 bash скрпит, в котором ты пулишь гит, собираешь контейнер после пула. И всё, и потом к этому скрипту привязать раннер на гите.

      4. Ты не внимательно изучил то, что описано выше. В докере у тебя ВСЁ что тебе нужно, можно и nginx добавить туда (что более правильно, но для старта будет слишком). Поэтому ты просто крутишь у себя базу, phpmyadmin и сам контейнер WP внутри которого у тебя php сервер и всё что с ним связано для правильной работы wp. Тебе ничего не нужно делать, всё заводится и работает как обычно.

    • Вот самый просто вариант обновить данные WP

      Как правильно задеплоить next js и wordpress с ci/cd из гитхаба?

    Как правильно задеплоить next js и wordpress с ci/cd из гитхаба?

    петов можно просто на верселе раскатывать

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Ирина WP Ответ

    Для связки Next.js + WordPress нормальная схема деплоя такая: WordPress живёт как backend/API, Next.js как отдельное приложение, перед ними nginx или другой reverse proxy. Не смешивайте это в одну папку через FTP, иначе CI/CD быстро превратится в ручной хаос.

    Практичный вариант на VPS — Docker Compose:

    services:
      next:
        build: ./frontend
        restart: always
        environment:
          WORDPRESS_API_URL: https://api.example.com/wp-json
    
      wordpress:
        image: wordpress:php8.2-fpm
        restart: always
        volumes:
          - ./wp:/var/www/html
    
      db:
        image: mysql:8.0
        restart: always
        volumes:
          - db_data:/var/lib/mysql
    
    volumes:
      db_data:

    services: next: build: ./frontend restart: always environment: WORDPRESS_API_URL: https://api.example.com/wp-json wordpress: image: wordpress:php8.2-fpm restart: always volumes: - ./wp:/var/www/html db: image: mysql:8.0 restart: always volumes: - db_data:/var/lib/mysql volumes: db_data:

    Nginx проксирует основной домен на Next.js, а api.example.com или /wp на WordPress. База должна храниться в volume или во внешнем MySQL, но обязательно с регулярным бэкапом.

    GitHub Actions обычно делает так: собирает Next.js, подключается по SSH к серверу, делает git pull, docker compose build, docker compose up -d. WordPress-код, тема и плагины тоже могут быть в репозитории, но загрузки uploads и база не должны перетираться деплоем.

    Перед продом сделайте staging. На нём проверьте CORS, домены, переменные окружения, cache revalidate, авторизацию API и sitemap. Самая частая ошибка — задеплоить фронт, который ходит в локальный или staging API.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно