RE:NODE

Strapi პროდაქშენში: გარემოს ცვლადები, ბაზა, ატვირთვები და განახლება

ავტორი RE:NODE-ის გუნდი
15 წუთის საკითხავი


Strapi-ის პროდაქშენში გაშვება ექვს გადაწყვეტილებამდე დადის, რომლებსაც ერთხელ იღებ და იწერ: საიდუმლოების ნაკრები .env-ში, რომელიც გაშვების შემდეგ აღარასოდეს იცვლება; მონაცემთა ბაზა, რომლის backup-იც შეგიძლია (SQLite ერთი პატარა საიტისთვის, PostgreSQL ყველაფრისთვის, სადაც რედაქტორები და ტრაფიკია); ადგილი ატვირთული ფაილებისთვის, რომელიც ხელახალ build-ს გადაურჩება; ადმინ-პანელი, აწყობილი NODE_ENV=production-ით; საჯარო url, რომელიც ემთხვევა იმას, რასაც reverse proxy ემსახურება; და განახლების წესი, რომელიც backup-ით იწყება. ადმინ-პანელის მშვიდად ასაწყობად Strapi-ს დაახლოებით 2 GB მეხსიერება სჭირდება, მოთხოვნების მომსახურებისთვის კი ამის შემდეგ ბევრად ნაკლები. ეს ექვსი რამ სწორად გააკეთე და Strapi იქნება წყნარი Node პროცესი პორტზე 1337. ერთში შეცდი - და ამას იმ დღეს გაიგებ, როცა რედაქტორი შევა სისტემაში და ყველა API ტოკენი მუშაობას შეწყვეტს.

ეს სახელმძღვანელო Strapi 5-ს აღწერს, რომელიც მიმდინარე ძირითადი ვერსიაა, და აღნიშნავს, სად განსხვავდება Strapi 4. ფაილების სახელები ნაჩვენებია როგორც .js; TypeScript-ის პროექტში იგივე ფაილებია, ოღონდ .ts გაფართოებით.

როგორაა აწყობილი Strapi-ის აპლიკაციის სერვერი#

Strapi არის Node.js აპლიკაცია ორი ნახევრით, რომლებიც ერთ პროცესში მუშაობს. პირველი კონტენტის API-ია: REST (და GraphQL, თუ პლაგინს დაამატებ) მისამართზე /api, რომელიც შენ მიერ განსაზღვრული კონტენტის ტიპებიდან გენერირდება. მეორე ადმინ-პანელია, React-ის აპლიკაცია მისამართზე /admin, სადაც რედაქტორები კონტენტს წერენ, შენ კი დეველოპმენტის დროს კონტენტის ტიპებს ქმნი.

ეს დაყოფა ხსნის პროდაქშენის Strapi-ის ყველაზე მოულოდნელ წესს: Content-Type Builder მხოლოდ დეველოპმენტის რეჟიმში მუშაობს. strapi develop პროექტს ადევნებს თვალს და მოდელის შეცვლისას გადაიტვირთება; strapi start ამას არ აკეთებს და კონსტრუქტორი მხოლოდ წასაკითხადაა. კონტენტის ტიპები კოდია - JSON სქემები src/api-სა და src/components-ში - და მათი ადგილი Git-შია. მათ დეველოპმენტის ასლზე ცვლი, აკეთებ commit-ს და deploy-ს, ზუსტად ისე, როგორც მონაცემთა ბაზის მიგრაციას ნებისმიერ სხვა ფრეიმვორკში.

გაშვებისას Strapi ამ სქემებს მონაცემთა ბაზას ადარებს და ცხრილებს მათ შესაბამისობაში მოჰყავს. ეს მოსახერხებელია და, ამავე დროს, ფრთხილად მოსაპყრობი: გადარქმეული ველი ბაზისთვის ერთი წაშლილი ველი და ერთი ახალი ველია, და ძველი სვეტის მონაცემები ახალ სახელს არ მიჰყვება. ველები ჯერ პროდაქშენის მონაცემების ასლზე გადაარქვი, არასოდეს ცოცხალ საიტზე.

სამი ბრძანება, რომლებსაც გამოიყენებ; ყველა მათგანი უკვე განსაზღვრულია package.json-ში, რომლითაც ახალი პროექტი იქმნება:

ბრძანებარას აკეთებს
npm run developდეველოპმენტის რეჟიმი, ავტომატური გადატვირთვა, Content-Type Builder ჩართულია
npm run buildაწყობს ადმინ-პანელს (და აკომპილირებს TypeScript-ს)
npm run startპროდაქშენის რეჟიმი, ავტოგადატვირთვისა და კონსტრუქტორის გარეშე
HTTPS 443HTTP 1337ატვირთვის პროვაიდერიმედიის ბმულებიბრაუზერისაიტი ან რედაქტორიReverse proxyHTTPS, შენი დომენიStrapiNode, პორტი 1337მონაცემთა ბაზაSQLite ან PostgreSQLS3 bucketატვირთული მედია
მოთხოვნის გზა ბრაუზერიდან Strapi-მდე და მის მონაცემებამდე

გარემოს ცვლადები და საიდუმლოებები#

ახალი პროექტი იღებს .env ფაილს ამ ჩანაწერებით, რომელთაგან თითოეულს პროექტის გენერატორი შემთხვევითი მნიშვნელობით ავსებს. პროდაქშენში თითოეული უნდა იყოს დაყენებული, ამ გარემოსთვის უნიკალური და გაშვების დღიდან უცვლელი.

ცვლადივინ კითხულობსრა ფუჭდება, თუ შეიცვალა
APP_KEYSconfig/server.jsხელმოწერილი სესიის cookie-ები ძალას კარგავს
API_TOKEN_SALTconfig/admin.jsყველა API ტოკენი წყვეტს მუშაობას
ADMIN_JWT_SECRETconfig/admin.jsყველა ადმინისტრატორი გამოდის სისტემიდან
TRANSFER_TOKEN_SALTconfig/admin.jsგადაცემის ტოკენები წყვეტს მუშაობას
JWT_SECRETconfig/plugins.jsმომხმარებლების შესვლის სესიებს ვადა გასდის

APP_KEYS მძიმით გამოყოფილი სიაა და არა ერთი მნიშვნელობა. Strapi მას env.array('APP_KEYS')-ით კითხულობს და გასაღებებით cookie-ებს აწერს ხელს; რამდენიმე გასაღები მათი როტაციის საშუალებას იძლევა. API_TOKEN_SALT API ტოკენების შენახვამდე მათ დასაჰეშად გამოიყენება, ამიტომ მისი შეცვლა ჩუმად აუქმებს ყველა ტოკენს, რომელიც შენს ფრონტენდს, build-ის კონვეიერს ან მობილურ აპლიკაციას აქვს. JWT_SECRET ეკუთვნის Users and Permissions პლაგინს - იმას, რომელიც ტოკენებს აძლევს შენს საიტზე დარეგისტრირებულ ადამიანებს, განსხვავებით ადმინში მომუშავე რედაქტორებისგან. Strapi 5-ის ახალი პროექტები ასევე აგენერირებენ ENCRYPTION_KEY-ს ადმინის დაშიფრული საიდუმლოებებისთვის; თუ შენს .env-ში ის არის, მას იგივენაირად მოეპყარი.

ფაილის დანარჩენი ნაწილი ჩვეულებრივი გაშვების პარამეტრებია:

.env
HOST=0.0.0.0PORT=1337NODE_ENV=productionAPP_KEYS=key1base64==,key2base64==,key3base64==,key4base64==API_TOKEN_SALT=replace-with-random-base64ADMIN_JWT_SECRET=replace-with-random-base64TRANSFER_TOKEN_SALT=replace-with-random-base64JWT_SECRET=replace-with-random-base64STRAPI_TELEMETRY_DISABLED=true

მნიშვნელობის დასაგენერირებლად გამოდგება 16 ან მეტი შემთხვევითი ბაიტის ნებისმიერი წყარო, base64-ში ჩაწერილი:

bash
$ openssl rand -base64 32$ node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

თუ APP_KEYS აკლია, Strapi გაშვებაზე უარს ამბობს strapi::session middleware-ის შეცდომით, რომელიც ამბობს, რომ აპლიკაციის გასაღებები სავალდებულოა. ეს კარგი მარცხია: ხმამაღალი, ჩატვირთვისას და აშკარა. ცუდი მარცხები ზემოთ აღწერილი ჩუმია, რომლებიც მაშინ ხდება, როცა ვინმე მომუშავე საიტზე საიდუმლოებებს თავიდან აგენერირებს. სტატია გარემოს ცვლადები და საიდუმლოებები ზოგად დისციპლინას აღწერს: როგორ დაიცვა ისინი კოდისა და ლოგებისგან.

SQLite თუ PostgreSQL#

Strapi მხარს უჭერს SQLite-ს, PostgreSQL-სა და MySQL-ს; არჩევანი DATABASE_CLIENT ცვლადით კეთდება, კონფიგურაცია კი config/database.js-ში. დაგენერირებული ფაილი კავშირის ყველა პარამეტრს გარემოდან კითხულობს, ასე რომ გადასვლა მხოლოდ ცვლადებისა და სწორი დრაივერის დაყენების საკითხია.

ცვლადირისთვისაანაგულისხმევი მნიშვნელობა დაგენერირებულ კონფიგში
DATABASE_CLIENTsqlite, postgres ან mysqlsqlite
DATABASE_FILENAMESQLite ფაილის გზა.tmp/data.db
DATABASE_HOSTსერვერის მისამართიlocalhost
DATABASE_PORTსერვერის პორტი5432 PostgreSQL-ისთვის
DATABASE_NAMEბაზის სახელიstrapi
DATABASE_USERNAMEმომხმარებელიstrapi
DATABASE_PASSWORDპაროლიstrapi
DATABASE_SSLTLS ბაზამდეfalse
DATABASE_SCHEMAPostgreSQL-ის სქემაpublic
DATABASE_POOL_MIN / MAXკავშირების პული2 / 10

SQLite ერთი ფაილია და მონაცემთა ბაზა თავად პროცესის შიგნით ცხოვრობს. მარკეტინგული საიტისთვის, პორტფოლიოსთვის ან დოკუმენტაციის CMS-ისთვის, ერთი-ორი რედაქტორით და ფრონტენდით, რომელიც სტატიკურად იწყობა ან ქეშირდება, ის სრულიად საკმარისია: კითხვა სწრაფია, ქსელში გავლა არ ხდება და სხვა არაფრის გაშვება ან გადახდა არ გიწევს. მისი საზღვრები ჩაწერა და კოპირებაა. ჩაწერები რიგრიგობით სრულდება, ამიტომ დატვირთული ადმინი და webhook-ით გაშვებული იმპორტი რიგში დადგება. ფაილი კი ცოცხალია: data.db-ის ასლი, გადაღებული მაშინ, როცა Strapi წერს, შეიძლება არ გაიხსნას.

ყურადღება მიაქციე ნაგულისხმევ გზას. .tmp/data.db დევს საქაღალდეში, რომლის სახელიც თითქოს წაშლას გთხოვს, ამიტომ დიდხანს მომუშავე სერვერზე ან შეგნებულად დატოვე ის ხელუხლებლად, ან ბაზა გადაიტანე DATABASE_FILENAME=data/strapi.db-ით და დარწმუნდი, რომ საქაღალდე არსებობს.

PostgreSQL სწორი არჩევანია, როგორც კი ამათგან რომელიმე გამოჩნდება: რამდენიმე ერთდროულად მომუშავე რედაქტორი, საჯარო API რეალური ტრაფიკით, სკრიპტებით იმპორტირებული კონტენტი ან შეთანხმებული backup-ების საჭიროება pg_dump-ით ისე, რომ საიტი არ გაჩერდეს. ამისთვის პროექტში pg პაკეტი გჭირდება:

bash
$ npm install pg
.env
DATABASE_CLIENT=postgresDATABASE_HOST=db.example.netDATABASE_PORT=5432DATABASE_NAME=strapiDATABASE_USERNAME=strapiDATABASE_PASSWORD=long-random-passwordDATABASE_SSL=false

თუ კავშირის ერთ სტრიქონს ამჯობინებ, DATABASE_URL-იც იკითხება. DATABASE_SSL=true დააყენე, როცა ბაზას ინტერნეტით უკავშირდები და არა კერძო ქსელით; სტატია PostgreSQL sslmode ხსნის, რას ამოწმებს სინამდვილეში თითოეული დონე. ნაგულისხმევი პული ათი კავშირით ერთ Strapi პროცესს ჰყოფნის; თუ რამდენიმე პროცესი გაქვს, მათი პულები შეკრიბე და ბაზის კავშირების ლიმიტს შეადარე, როგორც სტატია კავშირების პულები და ლიმიტები ხსნის.

არსებული საიტის SQLite-დან PostgreSQL-ზე გადატანა Strapi-ის საკუთარი ექსპორტითა და იმპორტით ხდება და არა ფაილის კონვერტაციით: გააკეთე ექსპორტი SQLite-ის ინსტანსიდან, ცვლადები ცარიელ PostgreSQL ბაზაზე მიმართე, ერთხელ გაუშვი Strapi, რომ ცხრილები შექმნას, გააჩერე და შემდეგ გააკეთე იმპორტი. ბრძანებები ქვემოთ, backup-ების ნაწილშია.

ატვირთვები: ლოკალური დისკი თუ S3 bucket#

ნაგულისხმევად Upload პლაგინი ფაილებს public/uploads-ში ინახავს და Strapi მათ თავად ემსახურება. ერთ სერვერზე მუდმივი დისკით ეს მუშაობს და სწორედ ასე იწყება ერთი დაწკაპუნებით დაყენებული Strapi. ობიექტური საცავისკენ სამი რამ გიბიძგებს: დისკი, რომელიც სურათებითა და დაგენერირებული მინიატურებით ივსება, deploy-ის პროცესი, რომელიც პროექტის საქაღალდეს ცვლის, და სურვილი, რომ მედია ისე გაიცეს, რომ ყოველი მოთხოვნა Node-ზე არ გაიაროს.

Strapi-ის ოფიციალური S3 პროვაიდერი არის @strapi/provider-upload-aws-s3. სახელის მიუხედავად, ის ნებისმიერ S3-თავსებად სერვისთან მუშაობს, თუ მას endpoint-ს მისცემ და, AWS-ის გარდა სერვისების უმეტესობისთვის, path-style მისამართებას.

bash
$ npm install @strapi/provider-upload-aws-s3
config/plugins.js
module.exports = ({ env }) => ({  upload: {    config: {      provider: 'aws-s3',      providerOptions: {        baseUrl: env('S3_PUBLIC_URL'),        s3Options: {          credentials: {            accessKeyId: env('S3_ACCESS_KEY_ID'),            secretAccessKey: env('S3_ACCESS_SECRET'),          },          region: env('S3_REGION'),          endpoint: env('S3_ENDPOINT'),          forcePathStyle: true,          params: {            Bucket: env('S3_BUCKET'),          },        },      },      actionOptions: {        upload: {},        uploadStream: {},        delete: {},      },    },  },});

ცვლადების სახელებს env(-ის შემდეგ შენ ირჩევ; ფიქსირებულია მხოლოდ სტრუქტურა. baseUrl ის საჯარო მისამართია, საიდანაც ფაილები გაიცემა, და შეიძლება API-ის endpoint-ისგან განსხვავდებოდეს, თუ bucket-ის წინ CDN ან პროქსი დგას. forcePathStyle: true აიძულებს მოთხოვნებს, წავიდნენ endpoint/bucket/key-ზე და არა bucket.endpoint/key-ზე - სტატია path-style და virtual-hosted S3-ში ხსნის, რატომ სჭირდება ეს თვითჰოსტინგის საცავების უმეტესობას.

ნაბიჯი, რომელიც ყველას რჩება, ადმინ-პანელის Content Security Policy-ია. strapi::security middleware სურათებს მხოლოდ საკუთარი წყაროდან უშვებს, ამიტომ პროვაიდერის შეცვლის შემდეგ ფაილები იტვირთება, მაგრამ Media Library-ში მინიატურები გაფუჭებულია. შენი bucket-ის ჰოსტი დაამატე img-src-სა და media-src-ში, ფაილში config/middlewares.js:

config/middlewares.js
module.exports = [  'strapi::logger',  'strapi::errors',  {    name: 'strapi::security',    config: {      contentSecurityPolicy: {        useDefaults: true,        directives: {          'connect-src': ["'self'", 'https:'],          'img-src': ["'self'", 'data:', 'blob:', 'market-assets.strapi.io', 'files.example.com'],          'media-src': ["'self'", 'data:', 'blob:', 'market-assets.strapi.io', 'files.example.com'],          upgradeInsecureRequests: null,        },      },    },  },  'strapi::cors',  'strapi::poweredBy',  'strapi::query',  'strapi::body',  'strapi::session',  'strapi::favicon',  'strapi::public',];

პროვაიდერის შეცვლა არსებულ ფაილებს არ გადაიტანს. ცვლილებამდე ატვირთული მედია კვლავ ლოკალურ დისკზე /uploads/...-ს მიუთითებს; ან ეს ფაილები ადგილზე დატოვე, ან გადატანა დაგეგმე როგორც ექსპორტი, პროვაიდერის შეცვლა და იმპორტი.

ადმინის build და მეხსიერება#

npm run build ადმინ-პანელს სტატიკურ ფაილებად აკომპილირებს. ის ერთხელ ეშვება ყოველ deploy-ზე და არა ყოველ მოთხოვნაზე, მაგრამ ეს Strapi-ის ყველაზე მეხსიერებამოთხოვნილი საქმეა: React-ის აპლიკაციის აწყობას ყველა პლაგინის ადმინის კოდით შეიძლება ხანმოკლედ გიგაბაიტზე საგრძნობლად მეტი დასჭირდეს, მაშინ როცა ამის შემდეგ მომუშავე სერვერი ხშირად რამდენიმე ასეულ მეგაბაიტზე ჩერდება. Strapi-ის deploy-ის დოკუმენტაცია მინიმუმად 2 GB RAM-ს ასახელებს.

სამი წესი build-ს პრობლემებისგან დაიცავს:

  1. build გააკეთე დაყენებული NODE_ENV=production-ით, რომ პანელი მინიფიცირებული და პროდაქშენის კონფიგურაციისთვის აწყობილი იყოს.
  2. build თავიდან გაუშვი ყველაფრის შემდეგ, რაც ადმინს ცვლის: ახალი პლაგინი, Strapi-ის განახლება, config/admin.js-ის ცვლილება, ადმინის გზის ან საჯარო URL-ის შეცვლა.
  3. თუ build JavaScript-ის heap-ის შეცდომით ვარდება, Node-ის ლიმიტი მხოლოდ ამ ბრძანებისთვის გაზარდე NODE_OPTIONS=--max-old-space-size=1536-ით (სერვერის მეხსიერებაზე ნაკლები) და წაიკითხე Node-ის მეხსიერების ლიმიტები, რომ გაიგო, რატომ არ უდრის ნაგულისხმევი მნიშვნელობა შენი გეგმის RAM-ს.

მეხსიერების მკაცრი ლიმიტის მქონე სერვერზე build, რომელიც მას გადააჭარბებს, არ ნელდება და არ გამოკეთდება; პროცესი კვდება. სიმპტომია build, რომელიც შუა გზაზე წყდება საკუთარი შეცდომის გარეშე. ეს შემთხვევა build-ისთვის უფრო დიდი გეგმით ან ზემოთ ნახსენები heap-ის დროშით სწორდება და არა ხელახალი ცდებით.

საჯარო URL, ადმინის გზა და reverse proxy#

Strapi უსმენს HOST-სა და PORT-ს - ნაგულისხმევად 0.0.0.0:1337 - და ელოდება, რომ მის წინ TLS-ისა და დომენისთვის reverse proxy იდგება. ორი პარამეტრი config/server.js-ში აიძულებს მას იქ სწორად მოიქცეს:

config/server.js
module.exports = ({ env }) => ({  host: env('HOST', '0.0.0.0'),  port: env.int('PORT', 1337),  url: env('PUBLIC_URL', 'https://cms.example.com'),  app: {    keys: env.array('APP_KEYS'),  },});

url საიტის საჯარო მისამართია სქემასთან ერთად. Strapi მას აბსოლუტური ბმულების შესაქმნელად იყენებს - ადმინის საკუთარი მისამართი, ლოკალური ატვირთვის პროვაიდერის ფაილების URL-ები, პაროლის აღდგენის წერილების ბმულები - ამიტომ თუ მას არ დააყენებ, მიიღებ http://0.0.0.0:1337/... ბმულებს, რომლებიც მხოლოდ თავად სერვერზე მუშაობს. თუ Strapi-ს ქვეგზაზე ემსახურები, მაგალითად https://example.com/cms, გზა url-ში ჩაწერე და ადმინი თავიდან ააწყვე.

მეორე პარამეტრი პროქსისადმი ნდობაა. პროქსის უკან Strapi ყოველ მოთხოვნას ხედავს როგორც უბრალო HTTP-ს პროქსის მისამართიდან, სანამ არ ეტყვი, რომ X-Forwarded-For-სა და X-Forwarded-Proto სათაურებს ენდოს. ოფციას ჰქვია proxy ფაილში config/server.js; მისი ფორმა შეიცვალა Strapi 4-სა (ლოგიკური მნიშვნელობა) და Strapi 5-ს (ობიექტი ცალკე გასაღებებით) შორის, ამიტომ შენი ვერსიის სერვერის კონფიგურაციის გვერდი ნახე და ძველ ფრაგმენტს ნუ დააკოპირებ. მის გარეშე კლასიკური შეცდომაა Cannot send secure cookie over unencrypted connection, როცა შესვლის პროცესი დაცული cookie-ს დაყენებას ცდილობს.

ადმინ-პანელი ნაგულისხმევად /admin-ზეა, მისი გზა კი config/admin.js-ში ყენდება. გადატანა მას უსაფრთხოს არ ხდის - API მაინც პასუხობს, სადაც არ უნდა იყოს - მაგრამ სკანერების ხმაურს ამცირებს. სტატია რას აკეთებს reverse proxy სათაურებს დეტალურად განიხილავს, ხოლო თუ Strapi-ის წინ საკუთარ nginx-ს იყენებ, nginx-ის reverse proxy-ის სახელმძღვანელოში მზა ბლოკია. გახსოვდეს, რომ nginx-ში client_max_body_size ნაგულისხმევად 1m-ია, რაც ერთ მეგაბაიტზე დიდ ნებისმიერ ატვირთვას 413 პასუხით ბლოკავს, სანამ Strapi მას დაინახავს.

Strapi გვთავაზობს /_health-ს, რომელიც ცარიელი 204-ით პასუხობს, როცა სერვერი მუშაობს - სასარგებლოა ხელმისაწვდომობის მონიტორისთვის, რომელსაც არ უნდა შესვლა ან ბაზაზე დამოკიდებული API-ის გამოძახება.

Backup-ები და აღდგენა#

ორი ფენაა და ორივე გჭირდება.

პირველი მონაცემთა ბაზა და ატვირთვებია, ფაილებად დაკოპირებული. PostgreSQL-ის შემთხვევაში pg_dump შეთანხმებულ დამპს იღებს, სანამ Strapi აგრძელებს მუშაობას - სტატია pg_dump და pg_restore ფორმატებსა და აღდგენას განიხილავს. SQLite-ის შემთხვევაში ფაილის უსაფრთხო ასლი გაჩერებული Strapi-ით კეთდება, ან ინსტრუმენტით, რომელიც თავად SQLite-ის backup API-ს იყენებს; ჩაწერის შუაში ფაილის უბრალო კოპირება ლატარიაა. ატვირთვები public/uploads-ში ჩვეულებრივი ფაილებია. პროექტის კოდთან და შენს .env-თან ერთად ეს სამი ნაწილი სრულ აღდგენას იძლევა.

მეორე ფენა Strapi-ის მონაცემთა გადაცემის საკუთარი ბრძანებებია, რომლებიც ბაზის ძრავისგან დამოუკიდებელ გადასატან არქივს ქმნიან:

bash
$ npm run strapi export -- --no-encrypt -f strapi-backup$ npm run strapi import -- -f strapi-backup.tar.gz

--no-encrypt-ის გარეშე არქივი იშიფრება გასაღებით, რომელსაც ბრძანება გკითხავს, და .tar.gz.enc სუფიქსს იღებს. არქივში კონტენტი, ატვირთული ფაილები და პროექტის კონფიგურაციაა. მასში არ არის ადმინისტრატორები და API ტოკენები, ამიტომ ის ბაზის backup-ს არ ცვლის - ეს ინსტრუმენტია SQLite-სა და PostgreSQL-ს შორის ან სერვერებს შორის გადასასვლელად. იმპორტი ჩაწერამდე სამიზნე ინსტანსში არსებულ კონტენტს შლის, ამიტომ არასოდეს მიმართო ის არასწორ ინსტანსს. strapi transfer იგივეს ცოცხლად აკეთებს ორ მომუშავე Strapi ინსტანსს შორის გადაცემის ტოკენით - სწორედ მას იცავს TRANSFER_TOKEN_SALT.

რაც არ უნდა აირჩიო, ერთხელ მაინც აღადგინე სადმე. სტატია backup-ები, რომლებიც მართლა აღდგება ხსნის, რატომ არის backup, რომელიც არავის აღუდგენია, მხოლოდ ჰიპოთეზა.

Strapi-ის უსაფრთხო განახლება#

Strapi ხშირად გამოდის და ადმინი ყოველ განახლებაზე თავიდან იწყობა, ამიტომ განახლებებს გამართული წესი სჭირდება და არა npm update. Strapi 5-ს მოყვება განახლების ინსტრუმენტი, რომელიც პაკეტების ვერსიებს ზრდის და კოდის ტრანსფორმაციებს უშვებს:

bash
$ npx @strapi/upgrade patch --dry$ npx @strapi/upgrade minor$ npx @strapi/upgrade major

patch და minor მიმდინარე ძირითადი ვერსიის ფარგლებში რჩება; major Strapi 4-დან 5-ზე გადასვლის გზაა, და ეს მიგრაციის პროექტია და არა განახლება - იცვლება პლაგინები, საკუთარი კოდი და მონაცემთა ბაზა. --dry გაჩვენებს, რა მოხდებოდა, ისე რომ არაფერს ჩაწერს.

წესი, რომელიც მუშაობს:

  1. გააკეთე მონაცემთა ბაზისა და ატვირთვების backup და არქივი ამ სერვერის გარდა სხვაგან შეინახე.
  2. განახლება დეველოპმენტის ასლზე გაუშვი, პროდაქშენის მონაცემების ახალი ასლით.
  3. გაუშვი npm run build, ჩართე აპლიკაცია და გაიარე ადმინიც და ის API-იც, რომელსაც შენი ფრონტენდი იყენებს.
  4. შედეგს commit გაუკეთე lock ფაილთან ერთად და ზუსტად ეს commit გააკეთე deploy-ზე.
  5. სერვერზე ადმინი თავიდან ააწყვე და გაუშვი; პირველი გაშვების ლოგს თვალი ადევნე, რადგან ბაზის სქემის ცვლილებები სწორედ მაშინ სრულდება.

Node.js-ის ვერსიაც შეამოწმე. Strapi-ის თითოეული გამოშვება Node-ის ლუწი LTS ვერსიების კონკრეტულ დიაპაზონს უჭერს მხარს; კენტ ვერსიაზე ან მხარდაჭერადასრულებულ ვერსიაზე მუშაობა განახლების შემდეგ ინსტალაციის შეცდომების ხშირი მიზეზია.

Strapi RE:NODE-ზე#

RE:NODE-ზე Strapi ერთი დაწკაპუნებით დასაყენებელი აპლიკაციაა აპლიკაციების ჰოსტინგის გვერდზე. ის სერვერის პირველი გაშვებისას ყენდება და იწყობა, მონაცემები კი SQLite-ში ინახება სერვერზე, ამიტომ პირველ რიგში გახსენი /admin და შექმენი ადმინისტრატორის ანგარიში. გეგმები 2 GB მეხსიერებიდან იწყება, რაც ადმინის build-ის საჭიროებას შეესაბამება. ფაილი .env პროექტის საქაღალდეშია და მისი რედაქტირება ფაილ-მენეჯერში ან SFTP-ით შეიძლება; სანამ მისამართს ვინმეს მისცემ, შეამოწმე, რომ ზემოთ მოცემული ცხრილის თითოეულ საიდუმლოს გრძელი შემთხვევითი მნიშვნელობა აქვს.

პანელი ამ სახელმძღვანელოში აღწერილ საოპერაციო ნაწილებს ფარავს. A ჩანაწერი პროქსის სლოტთან ნაჩვენებ მისამართზე მიმართე და სერტიფიკატი ავტომატურად გაიცემა და განახლდება, კლიენტის რეალური IP კი X-Forwarded-For-ში მოვა. backup-ის სლოტები ყველა გეგმაზეა, ეშვება ხელით ან Schedules ჩანართიდან და ინახება მანქანის გარეთ - იხილე backup-ები სახელმძღვანელოებში. რადგან SQLite ცოცხალი ფაილია, backup-ები წყნარ საათზე დაგეგმე ან ჯერ სერვერი გააჩერე. თუ SQLite აღარ გყოფნის, PostgreSQL სერვერი მოგცემს DATABASE_* მნიშვნელობებს ჩასასმელად, ხოლო S3 ობიექტური საცავის გეგმა - endpoint-ს, გასაღებებს და პირველ bucket-ს ატვირთვის პროვაიდერისთვის, path-style მისამართებით და რეგიონის ნებისმიერი სახელით.

მეხსიერების ლიმიტს რომ მიაღწევს, სერვერი ჩერდება და სუფთად გადაიტვირთება, swap-ის ნაცვლად - ეს არის ზემოთ აღწერილი მოკლული build-ის სიმპტომი: თუ npm run build ჩუმად წყდება, მიზეზი ესაა.

პრობლემების მოგვარება#

ადმინში შესვლა მუშაობს, მაგრამ deploy-ის შემდეგ ყველა გამოვიდა სისტემიდან. შეიცვალა ADMIN_JWT_SECRET, ჩვეულებრივ იმიტომ, რომ ახალი .env დააგენერირეს. ძველი მნიშვნელობა აღადგინე.

მიგრაციის შემდეგ ყველა API ტოკენი `401`-ს აბრუნებს. API_TOKEN_SALT განსხვავდება იმისგან, რომლითაც ტოკენები შეიქმნა. აღადგინე ის, ან შექმენი ახალი ტოკენები და ყველა კლიენტი განაახლე.

Media Library-ში მინიატურები გაფუჭებულია, თუმცა ფაილები იტვირთება. bucket-ის ჰოსტი აკლია img-src-ს ფაილში config/middlewares.js.

წერილებში ბმულები და მედიის URL-ები `0.0.0.0:1337`-ზე მიუთითებს. config/server.js-ში url არ არის დაყენებული. დააყენე და ადმინი თავიდან ააწყვე.

განახლების შემდეგ ადმინი ძველ ვერსიას აჩვენებს. ადმინი თავიდან არ აწყობილა. გაუშვი npm run build და გადატვირთე.

1 MB-ზე დიდი ატვირთვები `413`-ით ვარდება. ეს reverse proxy-ის მოთხოვნის ზომის ლიმიტია და არა Strapi.

ადმინში კონტენტის ტიპების რედაქტირება შეუძლებელია. პროდაქშენის რეჟიმში ხარ და ასეც უნდა იყოს. შეცვალე ისინი დეველოპმენტში და გააკეთე deploy.

FAQ#

საკმარისია თუ არა SQLite Strapi-სთვის პროდაქშენში?

პატარა საიტისთვის, ერთი-ორი რედაქტორით და ქეშირებული ან სტატიკურად აწყობილი ფრონტენდით - კი. ის ცუდად უმკლავდება ბევრ ერთდროულ ჩაწერას და backup-ისას სიფრთხილეს მოითხოვს, ამიტომ PostgreSQL-ზე გადადი, როგორც კი რამდენიმე ადამიანი ერთდროულად დაიწყებს რედაქტირებას ან API რეალურ ტრაფიკს მიიღებს.

შეიძლება თუ არა მოგვიანებით APP_KEYS-ის ან სხვა საიდუმლოებების შეცვლა?

შეიძლება, მაგრამ თითოეულ ცვლილებას თავისი ფასი აქვს: იმის მიხედვით, რომელს შეცვლი, ადმინისტრატორები გამოდიან სისტემიდან, API ტოკენები კვდება ან მომხმარებლების სესიები სრულდება. როტაცია შეგნებულად გააკეთე, თითო-თითოდ, და ტოკენების მფლობელებს წინასწარ შეატყობინე.

საჭიროა თუ არა build .env-ის შეცვლის შემდეგ?

ბაზის მონაცემებისა და საიდუმლოებებისთვის არა - ისინი სერვერის გაშვებისას იკითხება, ამიტომ გადატვირთვა საკმარისია. build საჭიროა საჯარო URL-ის, ადმინის გზის, პლაგინების ან Strapi-ის ვერსიის შეცვლის შემდეგ.

რატომ ვერ ვქმნი კონტენტის ტიპებს პროდაქშენის სერვერზე?

Strapi დეველოპმენტის რეჟიმის გარეთ Content-Type Builder-ს განზრახ თიშავს. მოდელები კოდია და მათი შეცვლა ცოცხალ სერვერზე ბაზის სქემას შეცვლიდა ვერსიების კონტროლში ყოველგვარი ჩანაწერის გარეშე.

ინახავს თუ არა strapi export ჩემს ადმინისტრატორებს?

არა. ადმინისტრატორები და API ტოკენები არქივში არ ხვდება. ბაზის დონის backup-იც იქონიე, ექსპორტი კი მიგრაციისა და გადატანის ინსტრუმენტად განიხილე.

გამოგადგათ?