Nextjs был выпущен в 2016 году. С тех пор он стал одной из самых больших рамок, которые поддерживают рендеринг Server-Side (SSR) с Reactjs & Nodejs. Будучи одной из первых компаний во Вьетнаме, которые применили NextJS для разработки продуктов, мы столкнулись с интересными проблемами и узнали на протяжении всего развития процессов развертывания. В сегодняшней теме я собираюсь поделиться о том, как мы имели дело с шагом развертывания, который помог нам достичь 2 больших вех.
- Веб-команда и команда по надежности сайта) работают самостоятельно.
- Только один шаг к производству.
Сопоставление URL к статическим ресурсам.
После создания совершенно нового проекта разработчики переходят на создание среды развертывания на основе правил SRE, чтобы иметь плавный рабочий процесс. Вот что нам обычно нужно:
- Определите доступный IP и порт.
- Зарегистрируйте услуги с доступным IP и портом.
- Спросите домен на состав услуг.
Для веб-приложения необходимо обрабатывать некоторые дополнительные предметы. Чтобы пойти вживую, вам необходимо указать некоторые статические ресурсы и активы, такие как файлы CSS, файлы JS и изображения … Поэтому нам нужно перечислить каждый ресурс с определенным URL, а затем работать с командой SRE на карту с IP & Port.
Например:
Ручной подход к этому простое и простое в настройке. Тем не менее, были бы проблемы, как следует следующие:
- Если у страницы есть много ресурсов. Нам нужно вручную перечислить каждый ресурс с определенным доменом. Это занимает много времени.
- И поскольку у нас есть много услуг и небольших веб-приложений. Следовательно, файл картографического конфигурации из команды SRE становится огромным.
- Иногда файл картографирования конфигурации имеет конфликты между сервисами, например, другая команда зарегистрировала URL на свой собственный ресурс.
Зависит от команды SRE
Было много услуг CHợ Tốt, которые зависят от команды SRE. Каждый раз, когда мы запускаем новое веб-приложение, нам нужно прийти на стол SRE и попросить отображать URL-адреса к статическим ресурсам, и когда конфигурация становится все сложнее, такая как этот URL был взят другим веб-приложением И мы сделали некоторые «взломать», чтобы сделать это работать. Следовательно, это приводит к созданию некоторых ошибок других веб-приложений. Затем мы вернемся к началу начала, чтобы найти другое решение.
По этим причинам команда Web Team & Sre приходит в решение, которое помогает автоматизации CI/CD трубопровода всей системы.
Когда код сливается на конкретную ветку (мастер или постановку или выпуск). Поток CI/CD будет запущен для выполнения. CI/CD имеет 3 этапа.
Докурировать Преобразование приложения для запуска внутри контейнера Docker.
Загрузка статических ресурсов на S3 После подключения веб-приложения мы выполняем несколько процессов, а затем начните загрузку всего каталога сборки на S3.
S3 Вот на самом деле CHợ Tốt Server, и мы применяем интерфейс AWS S3. Таким образом, загружая статические ресурсы на S3 означает загрузку на наш собственный сервер.
Развертывание Активация веб-приложения для работы в производственной среде.
Ниже приведена структура проекта. Вы можете найти это в CNA.
my-app ├── deployment/ └── post-build/ └──── index.js └── s3/ └──── index.js ├── app/ └── … └── next.config.js └── … ├── package.json
В этом разделе я охвачу 4 очка.
- Название ведра
- Полномочия
- Конфиги
- Развертывание
Название ведра
Первое, что мы делаем, это определить хорошее имя конвенции для ведра S3. Для этого мы вручную создаем с помощью команд AWS S3 SDK. Название ведра — это сочетание имени и окружающей среды обслуживания.
_
Например 1: Название сервиса «Chotot-Chaness». А также имя ведра
- Постановка: Chotot_vehicle_Stage.
- Производство: Chotot_vehicle_Production.
Например, 2: Название службы «Chotot-свойство». А также имя ведра
- Постановка: Chotot_property_Stage.
- Производство: Chotot_property_Production.
Полномочия
Мы используем GitLab через функцию «Secret Priblebles», которая предоставляет настройку позволяет добавлять «учетную информацию информацию» в качестве переменных среды. (Я считаю, что другие Ci/Cd есть та же функция, такая как Traviesci , Circleci , …).
Делая этот путь, мы следуем за Разделение проблем (SOC) Принцип дизайна. Развитие не нужно заботиться о развертывании или управлять полномочиями.
Конфиги
.gitlab-ci.yml.
stages: - dockerize - s3 - deploy dockerize: stage: dockerize script: -s3: stage: s3 script: - yarn install - yarn build - NODE_ENV=staging CDN_HOST_BUCKET=$CDN_HOST_BUCKET CDN_ACCESS_KEY_ID=$CDN_ACCESS_KEY_ID CDN_SECRET_ACCESS_KEY=$CDN_SECRET_ACCESS_KEY yarn s3:upload - NODE_ENV=production CDN_HOST_BUCKET=$CDN_HOST_BUCKET CDN_ACCESS_KEY_ID=$CDN_ACCESS_KEY_ID CDN_SECRET_ACCESS_KEY=$CDN_SECRET_ACCESS_KEY yarn s3:upload deploy: stage: deploy script: -
next.config.js.
const version = require('package.json').version; const config = { development: { assetPrefix: '' }, staging: { assetPrefix: `https://static.com/CHOTOT_VEHICLE_STAGING/${version}` }, production: { assetPrefix: `https://static.com/CHOTOT_VEHICLE_PRODUCTION/${version}` } }; module.exports = { assetPrefix: config.assetPrefix, generateBuildId: async () => { return 'build'; }, webpack(config, options) { return config; } };
Развертывание
Проблема
После создания веб-приложения NextJS у него есть каталог «.Next», а структура файлов отличается от доступа URL-адресов к статическим ресурсам.
Как видите, есть 2 разных пути.
.next/bundles/pages/index.js
против
/_next/build/page/index.js
Поэтому, если мы загружаем весь встроенный каталог на S3 и запустите наше веб-приложение. Это абсолютно не работает.
* * Решение
Из-за развертывания отделена от стадии разработки. Так что мы добавляем еще один этап перед загрузкой встроенного каталога на S3 под названием «Post-Build».
Этап «Post-Build» заботится о перерабатывании структуры файлов для соответствия структуре URL-адресов, которые указывают на файлы.
Например:
Сценарий после сборки
Чтобы создать пост-сборку, мы создали небольшой сценарий, который позволяет повторно структурировать встроенный каталог. Каждое серьезные изменения от Nextjs, которые создали новую структуру созданных файлов. По этой причине каждый из сценарий «пост-сборки» должен адаптировать с помощью основной версии NextJS.
Post-build.js — Nextjs 6
var fs = require('fs'); var mv = require('mv'); var dirs = ['app/.next/_next', 'app/.next/_next/build', 'app/.next/_next/build/page', 'app/.next/_next/static']; const PAGE_PATH = { old: 'app/.next/bundles/pages', new: 'app/.next/_next/build/page' }; const STATIC_PATH = { old: 'app/.next/static', new: 'app/.next/_next/static' }; // create dir dirs.forEach(item => { fs.mkdirSync(item); }); // move files mv(PAGE_PATH.old, PAGE_PATH.new, { mkdirp: true }, function(err) { if (err) console.log(err); }); mv(STATIC_PATH.old, STATIC_PATH.new, { mkdirp: true }, function(err) { if (err) console.log(err); });
Post-build.js — Nextjs 7
var fs = require('fs'); var mv = require('mv'); var dirs = [ 'app/.next/_next', 'app/.next/_next/static', ]; const STATIC_PATH = { old: 'app/.next/static', new: 'app/.next/_next/static' }; // create dir dirs.forEach(item => { fs.mkdirSync(item); }); mv(STATIC_PATH.old, STATIC_PATH.new, { mkdirp: true }, function(err) { if (err) console.log(err); });
Post-build.js — Nextjs 8
var fs = require('fs'); var mv = require('mv'); var dirs = ['.next/_next', '.next/_next/static']; const STATIC_PATH = { old: '.next/static', new: '.next/_next/static' }; // create dir dirs.forEach(item => { fs.mkdirSync(item); }); mv(STATIC_PATH.old, STATIC_PATH.new, { mkdirp: true }, function(err) { if (err) console.log(err); });
Загрузка на S3
После повторного структурирования встроенных файлов. Теперь все, что нам нужно, это какой-то код для загрузки всего каталога сборки на S3. Для этого мы создали небольшой пакет под названием « S3-загрузка », что помогает нам сделать это.
var path = require('path'); var version = require('./package.json').version; var Uploader = require('s3-uploading').default; var env = (process.env.NODE_ENV || 'staging').toUpperCase(); // CHOTOT_VEHICLE_PRODUCTION/1.0.1 var BUCKET_PATH = `_${env}/${version}`; const options = { s3: { accessKeyId: process.env.CDN_ACCESS_KEY_ID, secretAccessKey: process.env.CDN_SECRET_ACCESS_KEY, endpoint: process.env.CDN_HOST_BUCKET, region: '', ACL: 'public-read', sslEnabled: false }, upload: { directory: path.resolve(__dirname, '../../app/.next'), // path to built directory bucket: BUCKET_PATH } }; const job = new Uploader(options); job.upload();
Регистрация скриптов
Последнее, что нам нужно сделать, это регистрация сценариев для выполнения «Загрузка статических ресурсов на S3» шаг к Package.json
{ "scripts": { "s3:upload": "node ./deployment/s3", "start": "node ./server", "build": "next build app", "postbuild": "node ./deployment/post-build" }, }
Вот результаты постановки и производственной среды.
Как видите, мы управляем статическими ресурсами на основе версии от «Package.json». Мы следуем семантической версии, более подробно здесь Отказ В каждом выпуске мы обновляем версию, а затем загрузите их к S3.
С оптимизацией выше мы вырублены из N (N> 1) этапов развертывания на 1 шаг. Это приносит некоторые преимущества.
- Ускорить время разработки.
- Менее в зависимости от другой команды.
- Кэширование статической вариации ресурсов хорошо заботится (потому что мы храним все статические ресурсы на основе версии).
- Полностью контроль веб-командой.
Если вы заинтересованы в этом, убедитесь, что вы проверяете наши репо.
Оригинал: «https://dev.to/dzungnguyen179/nextjs-deployment-pipeline-on-s3-with-gitlab-ci-59en»