Tema
/
Interneto svetainių serverio dalies kūrimas GO
📖 Teorija

Vienas dvejetainis, laikina failų sistema ir prod sargybos

Dvylika SignFlow pamokų veikia tavo kompiuteryje. Ši pamoka jį išleidžia — į Railway, ant Postgres, pasiekiamą tikru URL. Didžioji dalis darbo jau padaryta: dvejetainis įterpia savo migracijas ir išteklius, o produkcijos sargybos — kodas, kurį parašei prieš kelias pamokas. Vienintelis tikras sprendimas — kur gyvena įkelti failai, ir suklysti čia yra klasikinis produkcijos siurprizas.

Vienas statinis dvejetainis, ant distroless. Daugiapakopis Dockerfile sukompiliuoja programą pilname Go atvaizde, tada nukopijuoja tik gautą dvejetainį į gcr.io/distroless/static — jokio apvalkalo, jokio paketų tvarkyklės, jokių OS liekanų, keli MB. Kadangi migracijos (//go:embed) ir statiniai ištekliai keliauja dvejetainio viduje, atvaizde nėra nieko, išskyrus dvejetainį. O dvejetainis pats paleidžia savo goose migracijas paleidžiantis — švarus diegimas migruoja pats; nėra atskiro migracijos žingsnio, kurį galėtum pamiršti.

Railway + Postgres, sujungti konfigūracija. railway.json nukreipia Railway į Dockerfile ir nustato /healthz sveikatos patikrą (galinis taškas iš 1 pamokos — jis pinguoja DB, tad nepasiekiama duomenų bazė praneša negaluojanti, o ne atiduoda 500). Postgres priedas suteikia DATABASE_URL. Railway įpurškia PORT. Programa visa tai skaito per config paketą.

Pamoka: Railway failų sistema laikina. Konteinerio vietinis diskas yra nutrinamas kiekvieno diegimo ir perkrovimo metu. LocalStore, rašantis į ./uploads, tobulas dev — ir spąstai prod: kiekvienas įkeltas dokumentas dingtų kito diegimo metu. Diegimas, veikiantis iki pirmo perdiegimo, — būtent tokio pobūdžio siurprizas, kuris pasiekia produkciją. Sprendimas — Railway Volume: nuolatinis diskas, primontuotas prie /data, su UPLOAD_DIR=/data/uploads. Pasirinktas vietoj S3/R2, nes tai vienas konfigūracijos pakeitimas — jokio naujo SDK, jokių kredencialų — o storage.Store sąsaja iš 8 pamokos jau daro objektų saugyklą švariu apkeitimu vėliau, jei kada nors išsiplėstum į kelis egzempliorius (Volume rišasi prie vieno). Sprendimą įrodysi 3 žingsnyje: įkelk, perdiek, atsisiųsk ir sumaišuok — baitas į baitą.

Produkcijos sargybos jau tavo kode. Čia nepridedi prod sutvirtinimo; tu jį įjungi su APP_ENV=prod, ir anksčiau parašytos sargybos suveikia:

  • config.Load atsisako pasileisti be SESSION_SECRET ir BASE_URL prod — jokių tylių nesaugių numatytųjų (6–7 pamokos).
  • Sesijos slapukas gauna Secure vėliavą (4 pamoka).
  • gorilla/csrf griežta Origin/Referer patikra aktyvi — atviro teksto apėjimas iš 6 pamokos buvo apgaubtas if !IsProd(), tad jis tik dev. Prod kryžminės kilmės POST atmetamas.

Tai atlygis už tai, kad niekada neįkodavai paslapties ir niekada nepraslydai pro saugumo patikrą numatytąja reikšme: pasirengimas produkcijai — vėliava, ne perrašymas.

Konsolės el. paštas lieka prod numatytasis — tyčia. EMAIL_SENDER numatytai console net produkcijoje. Tai sąmoningas mokymo pasirinkimas, ne tinginystė: jis leidžia tau įdiegti SignFlow ir paleisti visą srautą — registraciją, slaptažodžio atstatymą, pasirašytojų kvietimus — su jokiu API raktu ir jokia el. pašto paskyra. Nuorodos spausdinamos į Railway diegimo žurnalus; skaitai jas ten. Nustatyk EMAIL_SENDER=resend + RESEND_API_KEY, kai nori tikro el. pašto. email.Sender sąsaja iš 7 pamokos daro tai vienos-kintamojo jungikliu.

Ši pamoka:

  1. Dockerfile, .dockerignore, railway.json ir .env.example.
  2. Diegimas į Railway su Postgres priedu ir Volume — tada įrodyk, kad Volume veikia, pergyvendamas perdiegimą.

Gyva nuoroda: https://signflow-production-67f3.up.railway.app