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

    У меня был опыт работы 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


    .env

    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"


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

    Самый простой вариант - накатить на 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

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

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


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

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

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

    Как альтернативу можешь использовать FirstByte, дешевый и сердитый
    Ответ написан
    3 комментария
  • Что делать, не работает useEffect?

    Любая ошибка описывается библиотекой в консоли. Ты можешь посмотреть и уже после этого анализировать почему лог не отрабатывает
    Ответ написан
    Комментировать
  • Как поставить неразрывный пробел в строке объекта?

    \u00A0
    Ответ написан
    Комментировать
  • Как инициализировать слайдер после AJAX загрузки?

    В случае, если использовать observerUpdate, вы столкнётесь с сотнями повторений выполнения функции, для решения проблемы достаточно сделать повторную инициализацию после ajax запроса

    function loadProjectsPostType(category) {
    
                $.ajax({
                    url: '/wp-admin/admin-ajax.php',
                    type: 'POST',
                    cache: true, // включить кэширование
                    data: {
                        action: "load_projects",
                        category
                    },
    
                    beforeSend: () => $('.loader').addClass('active'),
    
                    success: function (data) {
                        $('.loader').removeClass('active');
                        $('.projects__items').html(data);
    
                        const projectSliders = document.querySelectorAll('.project-slider')
    
                        projectSliders && projectSliders.forEach(slider => {
    
                                let projectSlider = new Swiper(slider, {
    
                                    observer: true,
                                    observeParents: true,
                                    observeSlideChildren: true,
                                    navigation: {
                                        nextEl: slider.querySelector('.swiper-button-next'),
                                        prevEl: slider.querySelector('.swiper-button-prev'),
                                    },
                                    spaceBetween: 20,
                                    slidesPerView: 1,
    
                                })/* projectSlider */
                        }) /* forEach */
                    },
    
                    error: function(xhr, status, error) {
                        $('.error').addClass('active')
                        console.log("Ошибка запроса. Код ошибки: ",error);
                    }
                })
            }
    Ответ написан
    Комментировать