Strapi 5 su PostgreSQL ir Docker

Kodėl Strapi 5 verta dėmesio

Strapi penktoji versija atėjo su nemažai pasikeitimų, kurie iš tikrųjų daro šį headless CMS sprendimą dar patrauklesnį. Jei dar nesate susipažinę, Strapi leidžia greitai sukurti API be didesnių galvos skausmų – tiesiog apibrėžiate duomenų struktūras per patogią administravimo sąsają, ir viskas veikia. Penktoje versijoje kūrėjai pertvarkė nemažai vidinio kodo, pagerino našumą ir pridėjo naujų funkcijų, kurios ypač pravers didesniems projektams.

Kai pradedi naują projektą su Strapi, greitai iškyla klausimas – kaip viską organizuoti, kad būtų patogu ir plėtoti, ir diegti produkcijai? Čia ir ateina Docker pagalba. Konteinerizacija leidžia sukurti vienodą aplinką visiems komandos nariams ir lengvai perkelti projektą į bet kokį serverį. O PostgreSQL pasirinkimas vietoj standartinio SQLite duomenų bazės? Tai jau rimtesnių projektų reikalavimas – PostgreSQL yra patikima, greitai veikianti ir puikiai tinkanti produkcinei aplinkai.

Aplinkos paruošimas ir Docker konfigūracija

Prieš pradedant, jūsų kompiuteryje turėtų būti įdiegtas Docker ir Docker Compose. Tai pagrindas, be kurio toliau nepasitrauksime. Taip pat rekomenduoju turėti bent Node.js 18 versiją, nors pačiame konteineryje galite naudoti bet kokią.

Pirmiausia sukurkime projekto struktūrą. Man patinka laikyti viską tvarkingai, todėl sukuriu atskirą katalogą projektui:

„`
mkdir strapi5-project
cd strapi5-project
„`

Dabar sukursime docker-compose.yml failą, kuris aprašys mūsų servisus. Mums reikės dviejų pagrindinių konteinerių: vieno PostgreSQL duomenų bazei ir kito pačiam Strapi. Štai kaip atrodo mano konfigūracija, kurią naudoju realiuose projektuose:

„`yaml
version: ‘3.8’

services:
postgres:
image: postgres:15-alpine
container_name: strapi_postgres
restart: unless-stopped
environment:
POSTGRES_DB: strapi
POSTGRES_USER: strapi
POSTGRES_PASSWORD: strapi_password_change_me
volumes:
– postgres_data:/var/lib/postgresql/data
ports:
– „5432:5432”

strapi:
image: node:18-alpine
container_name: strapi_app
restart: unless-stopped
working_dir: /app
volumes:
– ./strapi:/app
ports:
– „1337:1337”
environment:
DATABASE_CLIENT: postgres
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_NAME: strapi
DATABASE_USERNAME: strapi
DATABASE_PASSWORD: strapi_password_change_me
NODE_ENV: development
APP_KEYS: tobemodified,tobemodified,tobemodified,tobemodified
API_TOKEN_SALT: tobemodified
ADMIN_JWT_SECRET: tobemodified
TRANSFER_TOKEN_SALT: tobemodified
JWT_SECRET: tobemodified
depends_on:
– postgres
command: sh -c „npm install && npm run develop”

volumes:
postgres_data:
„`

Svarbu paminėti, kad APP_KEYS ir kiti slapti raktai čia nurodyti tik demonstraciniams tikslams. Realiame projekte būtinai sugeneruokite saugius atsitiktinius rakus. Strapi dokumentacijoje rasite, kaip tai padaryti tinkamai.

Strapi projekto inicijavimas

Dabar turime sukurti patį Strapi projektą. Kadangi naudojame Docker, galime tai padaryti dviem būdais. Pirmas – paleisti laikinį konteinerį ir jame sukurti projektą. Antras – sukurti lokaliai ir tada perkelti į konteinerį. Aš paprastai renkuosi pirmą variantą, nes taip išvengiame galimų versijų nesuderinamumų.

Pirmiausia sukurkime katalogą Strapi failams:

„`
mkdir strapi
„`

Dabar paleiskime laikinį Node.js konteinerį ir jame sukurkime Strapi projektą:

„`
docker run -it –rm -v $(pwd)/strapi:/app -w /app node:18-alpine sh
„`

Konteineryje vykdome:

„`
npx create-strapi-app@latest . –quickstart –no-run
„`

Parametras –no-run svarbus, nes nenorime, kad Strapi iškart paleistų serverį su SQLite. Mes juk naudosime PostgreSQL. Kai komanda baigs darbą, galite išeiti iš konteinerio su exit.

Dabar jūsų strapi kataloge turėtų būti pilnai sukonfigūruotas Strapi projektas. Bet dar reikia patikslinti duomenų bazės konfigūraciją.

Duomenų bazės prisijungimo nustatymai

Strapi 5 versijoje konfigūracijos failai šiek tiek pasikeitė, bet principas išlieka tas pats. Atidarykite failą strapi/config/database.js (arba database.ts, jei naudojate TypeScript). Turėtumėte pamatyti kažką panašaus:

„`javascript
module.exports = ({ env }) => ({
connection: {
client: ‘sqlite’,
connection: {
filename: env(‘DATABASE_FILENAME’, ‘.tmp/data.db’),
},
useNullAsDefault: true,
},
});
„`

Mums reikia pakeisti šį failą, kad jis naudotų PostgreSQL. Štai kaip turėtų atrodyti naujas variantas:

„`javascript
module.exports = ({ env }) => ({
connection: {
client: ‘postgres’,
connection: {
host: env(‘DATABASE_HOST’, ‘localhost’),
port: env.int(‘DATABASE_PORT’, 5432),
database: env(‘DATABASE_NAME’, ‘strapi’),
user: env(‘DATABASE_USERNAME’, ‘strapi’),
password: env(‘DATABASE_PASSWORD’, ‘strapi’),
ssl: env.bool(‘DATABASE_SSL’, false),
},
debug: false,
},
});
„`

Pastebėsite, kad naudojame env() funkciją, kuri skaito reikšmes iš aplinkos kintamųjų. Tai puiki praktika, nes leidžia lengvai keisti nustatymus skirtingose aplinkose be kodo keitimo.

Dar vienas svarbus dalykas – turite įdiegti PostgreSQL kliento biblioteką. Atidarykite strapi/package.json ir įsitikinkite, kad dependencies sekcijoje yra:

„`json
„pg”: „^8.11.0”
„`

Jei jos nėra, pridėkite rankiniu būdu arba paleiskite konteinerį ir įvykdykite npm install pg.

Saugumo raktų generavimas

Grįžkime prie tų keturių APP_KEYS ir kitų slaptų raktų, kuriuos minėjau anksčiau. Strapi 5 reikalauja kelių skirtingų raktų saugumo tikslais. Negalite tiesiog palikti „tobemodified” reikšmių – tai būtų milžiniškas saugumo pažeidimas.

Lengviausias būdas sugeneruoti šiuos raktus – naudoti Node.js crypto modulį. Galite sukurti paprastą skriptą arba tiesiog paleisti Node.js REPL ir vykdyti:

„`javascript
require(‘crypto’).randomBytes(32).toString(‘base64’)
„`

Šią komandą paleiskite kelis kartus ir gautus rezultatus įrašykite į savo docker-compose.yml failo aplinkos kintamuosius. Kiekvienas raktas turėtų būti unikalus.

Dar geriau – naudokite .env failą vietoj tiesioginio raktų rašymo į docker-compose.yml. Sukurkite failą .env projekto šakniniame kataloge:

„`
DATABASE_PASSWORD=jūsų_saugus_slaptažodis
APP_KEYS=raktas1,raktas2,raktas3,raktas4
API_TOKEN_SALT=jūsų_sugeneruotas_raktas
ADMIN_JWT_SECRET=jūsų_sugeneruotas_raktas
TRANSFER_TOKEN_SALT=jūsų_sugeneruotas_raktas
JWT_SECRET=jūsų_sugeneruotas_raktas
„`

Tada docker-compose.yml faile galite nurodyti:

„`yaml
env_file:
– .env
„`

Ir nepamirškite pridėti .env į .gitignore failą! Tai kritiškai svarbu, kad nepatektų jautrūs duomenys į versijavimo sistemą.

Paleidimas ir pirmieji žingsniai

Dabar, kai viskas sukonfigūruota, galime paleisti mūsų aplinką. Projekto šakniniame kataloge vykdykite:

„`
docker-compose up -d
„`

Parametras -d reiškia „detached” režimą – konteineriai veiks fone. Jei norite matyti logus realiu laiku, paleiskite be šio parametro arba vėliau naudokite docker-compose logs -f.

Pirmas paleidimas gali užtrukti kelias minutes, nes Docker atsisiųs reikalingus image’us, o Strapi įdiegs visas priklausomybes. Galite stebėti progresą su:

„`
docker-compose logs -f strapi
„`

Kai pamatysite pranešimą, kad serveris veikia ant http://0.0.0.0:1337, galite atidaryti naršyklę ir eiti į http://localhost:1337/admin. Jus pasitiks Strapi registracijos forma – čia sukursite pirmąjį administratoriaus paskyrą.

Užpildykite formą su savo duomenimis. Šis vartotojas turės pilną prieigą prie sistemos, todėl naudokite stiprų slaptažodį. Po registracijos būsite nukreipti į Strapi administravimo panelę – tai jūsų pagrindinis darbo įrankis.

Content Types kūrimas ir API testavimas

Dabar pats metas išbandyti, kaip visa tai veikia. Strapi administravimo panelėje kairėje pusėje rasite „Content-Type Builder” – tai vieta, kur kuriate savo duomenų struktūras.

Sukurkime paprastą pavyzdį – tarkime, blog’o įrašų kolekciją. Spauskite „Create new collection type” ir pavadinkite jį „Article”. Strapi automatiškai sukurs API endpoint’us su tinkamu įvardžiavimu.

Pridėkite keletą laukų:
title (Text, short)
content (Rich text)
publishedAt (DateTime)
author (Text, short)

Išsaugokite, ir Strapi automatiškai perkraus serverį su nauja konfigūracija. Tai vienas iš dalykų, kurie man labiausiai patinka Strapi – nereikia rašyti jokio kodo, kad gautum veikiantį API.

Dabar eikite į „Content Manager” ir sukurkite kelis testavimo įrašus. Užpildykite laukus ir publikuokite juos. Bet jei bandysite pasiekti API endpoint’ą http://localhost:1337/api/articles, greičiausiai gausite tuščią atsakymą arba klaidos pranešimą. Kodėl? Nes pagal nutylėjimą Strapi 5 visi endpoint’ai yra apsaugoti.

Eikite į „Settings” -> „Users & Permissions Plugin” -> „Roles” -> „Public”. Čia galite nustatyti, kokius veiksmus gali atlikti neprisijungę vartotojai. Pažymėkite „find” ir „findOne” prie Article, išsaugokite, ir dabar API turėtų grąžinti jūsų sukurtus įrašus.

Produkcijos aplinkos paruošimas

Kol kas viskas veikia development režimu, bet realiam projektui reikia pasiruošti produkcijai. Yra keli svarbūs skirtumai tarp development ir production aplinkų.

Pirma, turėtumėte sukurti atskirą docker-compose.prod.yml failą produkcinei aplinkai. Pagrindiniai skirtumai:

„`yaml
strapi:
environment:
NODE_ENV: production
command: sh -c „npm install –production && npm run build && npm run start”
„`

Production režime Strapi veikia greičiau, nes nenaudoja hot-reload ir kitų development funkcijų. Taip pat turėtumėte:

1. Naudoti Nginx arba kitą reverse proxy prieš Strapi. Tai suteikia papildomą saugumo sluoksnį ir leidžia lengviau valdyti SSL sertifikatus.

2. Sukonfigūruoti tinkamus backup’us PostgreSQL duomenų bazei. Docker volume’ai yra patogūs, bet ne pakankamas backup sprendimas.

3. Apriboti portų prieinamumą. Produkcijoje nereikėtų eksponuoti PostgreSQL porto 5432 – jis turėtų būti prieinamas tik Strapi konteineriui.

4. Naudoti Docker secrets vietoj aplinkos kintamųjų jautriems duomenims. Docker Swarm arba Kubernetes turi geresnius mechanizmus slaptų duomenų valdymui.

Štai kaip galėtų atrodyti pagerintas production setup su Nginx:

„`yaml
version: ‘3.8’

services:
nginx:
image: nginx:alpine
container_name: strapi_nginx
restart: unless-stopped
ports:
– „80:80”
– „443:443”
volumes:
– ./nginx.conf:/etc/nginx/nginx.conf
– ./ssl:/etc/nginx/ssl
depends_on:
– strapi

postgres:
image: postgres:15-alpine
container_name: strapi_postgres
restart: unless-stopped
environment:
POSTGRES_DB: strapi
POSTGRES_USER: strapi
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
– postgres_data:/var/lib/postgresql/data
secrets:
– db_password

strapi:
build: ./strapi
container_name: strapi_app
restart: unless-stopped
environment:
NODE_ENV: production
DATABASE_CLIENT: postgres
DATABASE_HOST: postgres
DATABASE_PORT: 5432
DATABASE_NAME: strapi
DATABASE_USERNAME: strapi
DATABASE_PASSWORD_FILE: /run/secrets/db_password
volumes:
– ./strapi/public/uploads:/app/public/uploads
secrets:
– db_password
depends_on:
– postgres

secrets:
db_password:
file: ./secrets/db_password.txt

volumes:
postgres_data:
„`

Kaip visa tai veikia kartu ir ko tikėtis ateityje

Strapi 5 su PostgreSQL ir Docker kombinacija suteikia solidų pagrindą beveik bet kokio dydžio projektui. Gavote visiškai veikiantį headless CMS, kuris lengvai plečiamas, paprasta administruoti ir, kas svarbiausia, lengvai perkeliamas tarp skirtingų aplinkų.

Docker konteinerizacija reiškia, kad jūsų komandos nariai gali paleisti visą projektą viena komanda, nepriklausomai nuo to, ar jie dirba su Mac, Linux ar Windows. Nebereikia valandų praleisti konfigūruojant lokalią aplinką – tiesiog docker-compose up ir viskas veikia.

PostgreSQL pasirinkimas užtikrina, kad jūsų duomenys bus saugūs ir sistema veiks stabiliai net su dideliais duomenų kiekiais. Tai ne SQLite, kuri tinka tik prototipams – PostgreSQL yra rimtas sprendimas rimtiems projektams.

Keletas praktinių patarimų, kuriuos išmokau per laiką:

Visada laikykite atskirą docker-compose.override.yml failą asmeniniams nustatymams. Šis failas neturėtų būti versijavimo sistemoje ir leidžia kiekvienam kūrėjui turėti savo konfigūraciją.

Naudokite Docker volumes ne tik duomenų bazei, bet ir Strapi uploads katalogui. Kitaip prarasite visus įkeltus failus kaskart perkurdami konteinerius.

Reguliariai atnaujinkite Docker image’us. PostgreSQL ir Node.js gauna saugumo pataisymus, kuriuos svarbu įdiegti. Tiesiog pakeiskite versiją docker-compose.yml ir paleiskite docker-compose pull.

Jei projektas auga ir vieno serverio nebepakanka, Docker konteineriai lengvai perkeliami į Kubernetes ar kitą orkestracijų sistemą. Jūsų investicija į Docker konfigūraciją atsipirks vėliau.

Strapi 5 dar gana nauja versija, todėl tikėkitės, kad kai kurie plugin’ai gali dar neveikti arba reikalauti atnaujinimų. Bendruomenė aktyvi, bet migracija iš Strapi 4 užtrunka. Jei naudojate daug trečiųjų šalių plėtinių, patikrinkite jų suderinamumą prieš pradėdami projektą.

Visa tai gali atrodyti sudėtinga iš pradžių, bet kai viską sukonfigūruosite vieną kartą, toliau darbas teka sklandžiai. Strapi leidžia sutelkti dėmesį į verslo logiką ir turinio valdymą, o ne į infrastruktūros smulkmenas. O Docker užtikrina, kad „pas mane veikia” problema tampa praeities reliktu.

Daugiau

Zustand ir Redux Toolkit: state management