Deploy บน VPS
หน้านี้สอนอะไร
เว็บพร้อม Easy CMS บน Linux server เครื่องเดียวที่คุณดูแลเอง (Ubuntu หรือ Debian): Node.js, SQLite และไฟล์อัปโหลด บน disk ของเครื่อง, systemd คอยรันให้ตลอด, Caddy สำหรับ HTTPS และสำรองข้อมูลทุกวัน
ควรอ่านก่อน: เลือกที่ deploy, Migration และการ deploy
server เครื่องเดียวเป็นวิธีที่ง่ายและถูกที่สุดในการรัน Easy CMS server รันอยู่ตลอด จึงรัน งานตามเวลาเองทุกนาที และ SQLite ต้องการแค่ไฟล์เดียว
1. Node.js และ user
ติดตั้ง Node.js 22.12 ขึ้นไป (24 LTS) เช่นจาก nodejs.org หรือแพ็กเกจ NodeSource ของ distribution แล้วสร้าง user สำหรับรันเว็บและเป็นเจ้าของไฟล์:
node -v # v22.12 ขึ้นไป
sudo useradd --system --create-home --shell /usr/sbin/nologin cms
sudo mkdir -p /srv/site && sudo chown cms:cms /srv/site2. ตัวเว็บ
ในสิทธิ์ user cms นำโค้ดไปไว้ที่ /srv/site (git clone หรือคัดลอกไป) ใส่ secret ติดตั้ง และ build ให้ build บน server เครื่องนั้นเลย เพราะ native driver ของ SQLite ต้องตรงกับระบบของเครื่อง
sudo -u cms bash
cd /srv/site
git clone https://github.com/you/your-site.git .
printf 'EASY_CMS_SECRET=%s\nEASY_CMS_SETUP_CODE=%s\n' "$(openssl rand -hex 32)" "choose-a-phrase" > .env
chmod 600 .env
npm ci
npm run build # Next.js หรือ Nuxt; standalone server ไม่ต้อง build
exitถ้าไม่ตั้ง DATABASE_URL config sqlite({ url: process.env.DATABASE_URL ?? 'file:./cms.db' }) จะเก็บฐานข้อมูลที่ /srv/site/cms.db และไฟล์อัปโหลดไปอยู่ที่ /srv/site/uploads จะใช้ Postgres ก็ได้ ติดตั้งบน server หรือใช้แบบ hosted แล้วตั้ง DATABASE_URL ใน .env
3. systemd service
systemd start เว็บตอนเปิดเครื่อง รัน migration ก่อน start ทุกครั้ง และ restart ให้ถ้าเว็บหยุด
[Unit]
Description=Easy CMS site
After=network.target
[Service]
Type=simple
User=cms
WorkingDirectory=/srv/site
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/srv/site/.env
ExecStartPre=/usr/bin/npx easy-cms migrate
ExecStart=/usr/bin/npx next start
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target[Unit]
Description=Easy CMS site
After=network.target
[Service]
Type=simple
User=cms
WorkingDirectory=/srv/site
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/srv/site/.env
ExecStartPre=/usr/bin/npx easy-cms migrate
ExecStart=/usr/bin/node .output/server/index.mjs
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target[Unit]
Description=Easy CMS site
After=network.target
[Service]
Type=simple
User=cms
WorkingDirectory=/srv/site
Environment=NODE_ENV=production
Environment=PORT=3000
EnvironmentFile=/srv/site/.env
ExecStartPre=/usr/bin/npx easy-cms migrate
ExecStart=/usr/bin/npx easy-cms serve --trust-proxy
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetEnvironmentFile ส่ง .env ให้ server (Nuxt ไม่อ่าน .env เอง) และ WorkingDirectory ทำให้ file:./cms.db, migration และ uploads อยู่ในโปรเจกต์ เช็คตำแหน่งของ npx และ node ด้วย which npx แล้วแก้ path ให้ตรง จากนั้น:
sudo systemctl daemon-reload
sudo systemctl enable --now easy-cms
journalctl -u easy-cms -f # migration ที่รัน แล้วตามด้วย serverHTTPS ด้วย Caddy
Caddy ขอและต่ออายุใบรับรอง HTTPS ให้เอง ชี้ DNS ของโดเมนมาที่ server เปิด port 80 และ 443 ติดตั้ง Caddy แล้วใช้:
cms.example.com
reverse_proxy localhost:3000sudo systemctl reload caddyCaddy redirect HTTP ไป HTTPS ให้เอง และส่ง X-Forwarded-For, X-Forwarded-Proto และ X-Forwarded-Host จึงต้องเชื่อมัน: trustProxy: true ใน route handler ของ Next.js หรือ module ของ Nuxt (--trust-proxy สำหรับ standalone server ซึ่งอยู่ใน unit ข้างบนแล้ว) และตั้ง serverURL: 'https://cms.example.com' ใน config ถ้าใช้ nginx ให้ proxy ไปที่ port เดียวกันและตั้ง header เหล่านั้นเอง แล้ว redirect HTTP ไป HTTPS ด้วย server block บน port 80:
server {
listen 80;
server_name cms.example.com;
return 301 https://$host$request_uri;
}สำรองข้อมูล
ให้ Easy CMS สำรองฐานข้อมูลทุกวัน (ดู สำรองข้อมูล):
backups: { frequency: 'daily', at: '03:00', keep: 7 },ไฟล์สำรองอยู่ใน backups/ บน disk เดียวกัน จึงควรคัดลอกไฟล์สำรองและ uploads/ ไปไว้ที่อื่นด้วย สำรองข้อมูลอัตโนมัติ ใช้ cron กับ S3 หรือ rclone
การอัปเดต
cd /srv/site
sudo -u cms git pull
sudo -u cms npm ci
sudo -u cms npm run build
sudo systemctl restart easy-cms # migrate แล้ว startเว็บจะหยุดไม่กี่วินาทีระหว่าง restart
ขั้นต่อไป
- ความปลอดภัย: checklist สำหรับ server ที่เปิดสู่อินเทอร์เน็ต
- Docker: เว็บเดียวกันใน container