# Easy CMS 1.7: pooler ของ Postgres, log แบบ JSON, health check และ Docker image

> มีอะไรใหม่ตั้งแต่ Easy CMS 1.4 ถึง 1.7: ตั้งค่า pool ของ Postgres และใช้ PgBouncer ได้, log แบบ JSON พร้อม request id, health check ทุก setup, Docker image อย่างเป็นทางการ และ setup หลาย server ที่ทดสอบจริง

URL: https://easy-cms-website.vercel.app/th/blog/easy-cms-1-7-th  
Published: 2026-10-25  
Updated: 2026-10-26

Easy CMS 1.4 ทำให้งานเบื้องหลังรันครั้งเดียวไม่ว่าจะมีกี่ server ใช้ฐานข้อมูลร่วมกัน สาม release หลังจากนั้นเติมส่วนที่เหลือ: ทุกอย่างที่ทีมต้องใช้เพื่อรัน Easy CMS หลาย server หลัง load balancer และรู้ว่าแต่ละตัวกำลังทำอะไร ไม่มี release ไหน breaking และไม่ต้อง migrate

## setup ที่ทดสอบจริง ไม่ใช่แค่คาดว่าใช้ได้

หน้าใหม่ [สถาปัตยกรรมสำหรับ production](/th/docs/deploy/production) บอกว่ารองรับอะไรเมื่อ server เดียวไม่พอ: Postgres, storage แบบ S3 สำหรับไฟล์ upload, instance ที่เหมือนกันกี่ตัวก็ได้หลัง load balancer โดยไม่ต้องใช้ sticky session และ CDN ข้างหน้า และบอกตรง ๆ ว่าอะไรใช้ได้แค่ server เดียว (SQLite บนดิสก์ ไฟล์ upload บนดิสก์) และอะไรที่ไม่รองรับ (หลาย region, read replica)

ตอนนี้ CI ตรวจ setup นี้ทุกครั้งที่มีการเปลี่ยนแปลง: เปิดสอง instance บน Postgres และ bucket เดียวกันหลัง proxy แบบ round-robin, login ที่ตัวหนึ่งแล้วใช้ session ที่อีกตัว, upload ผ่านตัวหนึ่งแล้วดาวน์โหลดผ่านอีกตัว, นับการ login ผิดรวมทั้งสองตัว และให้ทั้งสองตัวรันการเผยแพร่ตามเวลาพร้อมกันเพื่อเช็คว่าแต่ละโพสต์ถูกเผยแพร่ครั้งเดียว

## ตั้งค่า connection ของ Postgres (1.5)

`postgres()` รับ `prepare`, `statementTimeoutMs`, `idleTimeoutMs`, `connectTimeoutMs` และ `applicationName` และ connection จะแสดงเป็น `easy-cms` ใน `pg_stat_activity`

```ts
db: postgres({ url: process.env.DATABASE_POOLER_URL, max: 2, prepare: false })
```

บน serverless และเมื่อมีหลาย instance ให้ต่อผ่าน pooler CI รันเทสต์ของ Postgres ทั้งหมดผ่าน PgBouncer แบบ transaction mode หน้า[ฐานข้อมูล](/th/docs/databases#connections) อธิบายขนาด pool และเมื่อไรควรปิด prepared statement

องค์กรที่อยากแยก CMS ออกจากข้อมูลธุรกิจ ให้ CMS มี schema และ role ของตัวเองได้ คู่มือใหม่[แยกฐานข้อมูลจากแอป](/th/docs/database-isolation) อธิบายสี่ระดับ ตั้งแต่ใช้ฐานข้อมูลร่วมกันไปจนถึงแยก server พร้อม SQL สำหรับย้ายเว็บที่มีอยู่แล้ว

## log แบบ JSON และ request id (1.6)

```ts
logs: { format: 'json' }
```

หรือตั้ง `EASY_CMS_LOG_FORMAT=json` บน host ทุกบรรทัดจะเป็น JSON หนึ่ง object มีเวลา ระดับ ข้อความ และ stack ของ error พร้อมส่งเข้า Datadog, Loki หรือ CloudWatch ทุก response ของ API มี header `X-Request-Id` ทุกบรรทัดที่ log ระหว่างตอบ request นั้นมี id เดียวกัน และถ้า load balancer ส่ง id มาจะใช้ค่านั้นต่อ เมื่อเปิด JSON แต่ละ request ยังได้หนึ่งบรรทัดที่บอก path, status และเวลาที่ใช้ ดู[Log](/th/docs/deployment#logs)

## Health check (1.7)

ตอนนี้ทุก setup ตอบ probe สองตัวใต้ path ของ API:

- `/api/cms/healthz` ตอบ `ok` เมื่อ process ยังทำงาน โดยไม่แตะฐานข้อมูล
- `/api/cms/readyz` ตอบ `200` เมื่อฐานข้อมูลตอบและไม่มี migration ค้าง ไม่อย่างนั้นตอบ `503`

ให้ load balancer หรือ readiness probe ของ Kubernetes เรียก `readyz` และให้ liveness เรียก `healthz` ทั้งสองตัวตอบได้แม้ CMS เริ่มไม่ขึ้น และไม่ถูกเขียนลง log ของ request ดู[Health check](/th/docs/deployment#health-checks)

## Docker image อย่างเป็นทางการ

`ghcr.io/maritonx/easy-cms` รัน `easy-cms serve` พร้อม adapter ของ SQLite และ Postgres, storage แบบ S3 และอีเมล SMTP เพิ่ม config และ migration ของคุณ:

```dockerfile
FROM ghcr.io/maritonx/easy-cms:1
COPY easy-cms.config.ts ./
COPY easy-cms ./easy-cms
```

image รันด้วย user ที่ไม่ใช่ root เช็ค `/readyz` และมีทั้ง amd64 และ arm64 ทุก release จะ build ให้เอง ดู[Docker](/th/docs/deploy/docker#the-official-image)

## อื่น ๆ

- logout บนหน้าที่ยังไม่ได้บันทึกจะถามก่อน และถ้าเลือกอยู่ต่อจะยัง login อยู่ (1.4.3)
- การอ่านด้วย `locale: 'all'` มี type ตรงกับข้อมูลที่ได้จริง (1.4.2)

## การอัปเกรด

อัปเกรดทุกแพ็กเกจพร้อมกัน ไม่ต้อง migrate:

```bash
npm install @easy-cms/core@latest easy-cms@latest
```

[หน้า changelog](/changelog) มีทุกเวอร์ชัน
