SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-10-20

วิธีติดตั้ง Supabase บน VPS ด้วย Docker แบบละเอียด

เรียนรู้วิธีรัน Supabase บนเซิร์ฟเวอร์ส่วนตัวด้วย Docker Compose ตั้งแต่การตั้งค่าไฟล์ .env การเปลี่ยนค่า secrets ที่สำคัญ ไปจนถึงการจัดการ RAM และขั้นตอนการอัปเดตระบบโดยข้อมูลไม่สูญหาย

สิ่งที่คุณกำลังสร้าง

การทำ Self-hosting Supabase คือการรัน Docker Compose stack อย่างเป็นทางการบนเซิร์ฟเวอร์ของคุณเอง ซึ่งประกอบด้วย Postgres, REST API ที่อยู่ด้านหน้า, บริการยืนยันตัวตน (auth service), พื้นที่จัดเก็บไฟล์, ระบบ Realtime websockets และแดชบอร์ด Studio คุณเพียงแค่โคลน repository แก้ไขไฟล์ .env หนึ่งไฟล์ และเริ่มการทำงานของคอนเทนเนอร์ 11 รายการ ซึ่งทั้งหมดจะทำงานร่วมกันเสมือนโปรเจกต์ Supabase ที่คุณควบคุมเอง

การติดตั้งนั้นสั้นและง่าย ส่วนที่มักจะเกิดปัญหาคือไฟล์ .env ซึ่งมาพร้อมกับค่า demo secrets ที่ถูกเผยแพร่ไว้ใน repository หากเริ่มการทำงานของ stack ด้วยค่าเริ่มต้นเหล่านี้ ระบบจะเปิดกว้างให้ทุกคนที่พบเข้าถึงได้ คู่มือนี้จะครอบคลุมถึง secrets ที่คุณต้องเปลี่ยน หน้าที่ของแต่ละบริการ ปริมาณหน่วยความจำที่ stack ต้องการจริง ๆ และวิธีการอัปเดตโดยไม่ลบฐานข้อมูลของคุณ

หากคุณยังใหม่กับ Compose โปรดอ่าน พื้นฐาน Docker Compose บน VPS ก่อน เนื้อหาทั้งหมดด้านล่างนี้ตั้งสมมติฐานว่า docker compose version แสดงเวอร์ชันออกมาแล้ว

สิ่งที่อยู่ใน stack จริงๆ

Supabase ไม่ใช่โปรแกรมเดียว ไฟล์ Compose จะเริ่มการทำงานของบริการแยกส่วนหลายรายการบนเครือข่ายเดียวกัน การเข้าใจว่าแต่ละส่วนคืออะไรจะช่วยให้คุณเปลี่ยนรายชื่อ container จำนวนมากให้กลายเป็นสิ่งที่สามารถตรวจสอบและแก้ไขปัญหาได้

  • db คือ PostgreSQL ที่โหลดส่วนขยายของ Supabase ไว้ บริการอื่นทั้งหมดจะติดต่อกับส่วนนี้ หาก container นี้ไม่พร้อมใช้งาน บริการอื่นทั้งหมดก็จะล้มเหลวตามไปด้วย
  • api-gw คือ API gateway นับตั้งแต่รุ่นเดือนสิงหาคม 2026 เป็นต้นมา ส่วนนี้จะรัน Envoy; ก่อนหน้านั้นคือบริการที่ชื่อว่า kong และ Kong ยังคงมีให้เลือกใช้เป็นตัวเลือกเสริม โดยจะฟังคำขอที่พอร์ต 8000 และทำหน้าที่ส่งต่อ /rest/v1/, /auth/v1/ และ /storage/v1/ ไปยัง backend ที่ถูกต้อง นี่เป็น container เพียงรายการเดียวที่คุณควรเปิดให้เข้าถึงจากภายนอก
  • rest คือ PostgREST ซึ่งจะอ่าน schema ของ Postgres และให้บริการในรูปแบบ REST API ดังนั้นตารางใหม่ที่สร้างขึ้นจะกลายเป็น endpoint ใหม่โดยไม่ต้องเขียนโค้ดเพิ่ม
  • auth คือ GoTrue ซึ่งทำหน้าที่ออก JSON web tokens (JWT) เพื่อระบุตัวตนของผู้ใช้งาน
  • storage และ imgproxy จัดการเรื่องการอัปโหลดไฟล์และการปรับขนาดรูปภาพ
  • realtime ทำหน้าที่ส่งข้อมูลการเปลี่ยนแปลงในฐานข้อมูลผ่าน websockets
  • studio และ meta คือ dashboard และ admin API ที่อยู่เบื้องหลัง
  • functions คือ edge runtime ที่ใช้ Deno และ supavisor คือตัวจัดการ connection pool ของ Postgres

ระบบ log และ analytics (Logflare ร่วมกับ vector) ถูกนำออกจากไฟล์ Compose เริ่มต้นในเดือนมิถุนายน 2026 ปัจจุบันส่วนนี้กลายเป็นไฟล์เสริมที่คุณต้องเลือกเปิดใช้งานเองด้วย sh run.sh config add logs ซึ่งเป็นการซ้อนทับไฟล์ Compose ตามที่อธิบายไว้ใน การรัน stack เดียวจากไฟล์ Compose หลายไฟล์

รายการข้างต้นคือเหตุผลว่าทำไมตัวเลขทรัพยากรที่ระบุด้านล่างจึงเป็นเช่นนั้น คุณไม่ได้กำลังรันแค่ฐานข้อมูล แต่คุณกำลังรันฐานข้อมูลพร้อมกับบริการสนับสนุนอีกสิบรายการ

การจัดสรรทรัพยากร: วางแผนสำหรับ RAM ขนาด 8 GB

ณ เดือนกรกฎาคม 2026 stack นี้ใช้หน่วยความจำแบบ resident memory ขณะ idle อยู่ที่ประมาณ 2.5 ถึง 3 GB ในการติดตั้งใหม่ ก่อนที่จะมีการนำข้อมูลของคุณเข้าหรือมี traffic เข้ามา โดยบริการ analytics และกระบวนการ Studio Node.js เป็นส่วนที่ใช้หน่วยความจำมากที่สุดสองอันดับแรก ปัจจุบัน analytics ไม่ได้เป็นส่วนหนึ่งของ stack เริ่มต้นแล้ว ดังนั้นจะใช้หน่วยความจำก็ต่อเมื่อคุณเปิดใช้งานการเขียนทับ log เท่านั้น เซิร์ฟเวอร์ขนาด 2 GB จะสามารถเริ่ม container ได้ แต่จะถูก kernel สั่งยุติการทำงานด้วย out of memory killer ซึ่งอาการที่พบคือ container จะค้างอยู่ในสถานะเริ่มทำงานใหม่ซ้ำๆ พร้อม exit code 137 เอกสารการ self-host ของ Supabase ที่ตรวจสอบเมื่อเดือนตุลาคม 2026 ระบุความต้องการขั้นต่ำไว้ที่ RAM 4 GB, CPU 2 cores และ SSD 40 GB ส่วนสเปกที่แนะนำคือ RAM 8 GB, CPU 4 cores และ SSD 80 GB

ควรจัดสรร RAM ขนาด 8 GB และ 4 vCPU สำหรับงานที่คุณต้องใช้งานจริง ขนาด 4 GB สามารถใช้ได้สำหรับ instance เพื่อการพัฒนาส่วนตัว หากคุณยอมรับได้ว่าการรัน query หนักๆ พร้อมกับใช้งาน Studio จะทำให้ระบบทำงานช้าลง พื้นที่จัดเก็บข้อมูลก็มีความสำคัญเช่นกัน เนื่องจาก Postgres, storage volume และข้อมูล log (หากคุณเปิดใช้งาน) ทั้งหมดจะถูกเก็บไว้ภายใต้ไดเรกทอรีของโปรเจกต์ ให้เริ่มต้นที่ 40 GB แล้วคอยตรวจสอบการใช้งาน การนับจำนวนบริการก่อนเลือกแผนเซิร์ฟเวอร์เป็นนิสัยที่ดีสำหรับการทำ self-host ทุกประเภท เนื่องจาก PhotoPrism และ Immich ก็มีข้อกำหนดขั้นต่ำของ RAM เช่นกัน โดยหน้า quick start ของ Immich ที่ตรวจสอบเมื่อเดือนตุลาคม 2026 ระบุว่าต้องการ RAM อย่างน้อย 6 GB และ CPU 2 cores หากสเปกนี้เกินความจำเป็นสำหรับโปรเจกต์ของคุณในขณะนี้ ให้ลองเปรียบเทียบกับ สิ่งที่แผนบริการฟรีบนคลาวด์ของ Supabase มีให้ เนื่องจากแอปขนาดเล็กที่ใช้พื้นที่ไม่เกิน 500 MB และไม่มีช่วงที่ไม่ได้ใช้งานนานเกินหนึ่งสัปดาห์ อาจสามารถรันบนนั้นได้โดยไม่มีค่าใช้จ่าย

การติดตั้ง: โคลน repository อย่างเป็นทางการ

เส้นทางที่รองรับคือการคัดลอกไดเรกทอรี docker ออกจาก repository หลักไปยังไดเรกทอรีโปรเจกต์ของคุณเอง การแยกส่วนนี้มีความสำคัญ เพราะหมายความว่าการทำ git pull ในภายหลังจะไม่เขียนทับ .env ของคุณ

git clone --depth 1 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/* supabase-project
cp supabase/docker/.env.example supabase-project/.env
cd supabase-project
docker compose pull

docker compose pull จะดาวน์โหลดอิมเมจขนาดหลายกิกะไบต์ กระบวนการควรสิ้นสุดโดยที่ทุกบริการมีสถานะเป็น Pulled หากเกิดข้อผิดพลาด manifest unknown ในขั้นตอนนี้ หมายความว่าแท็กอิมเมจที่ระบุไว้ถูกลบออกจากต้นทางแล้ว วิธีแก้ไขคือการดึง repository เวอร์ชันใหม่มาแทนการแก้ไขแท็กด้วยตนเอง

ความลับที่คุณต้องเปลี่ยนก่อนการเริ่มระบบครั้งแรก

ให้ดำเนินการส่วนนี้ก่อนเริ่ม stack ไม่ใช่หลังจากนั้น ค่าเหล่านี้หลายรายการจะถูกเขียนลงในข้อมูลเมื่อบูตครั้งแรก ดังนั้นการเปลี่ยนในภายหลังหมายถึงการต้องรีเซ็ตฐานข้อมูลใหม่ทั้งหมด

repository นี้มีตัวสร้าง (generator) ที่ผลิตค่าทุกอย่างได้อย่างถูกต้อง รวมถึง API key สองรายการที่ต้องลงนามด้วย JWT secret ใหม่ของคุณ

sh utils/generate-keys.sh --update-env

สคริปต์ดังกล่าวจะเขียนค่าใหม่สำหรับ JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, SECRET_KEY_BASE, REALTIME_DB_ENC_KEY, VAULT_ENC_KEY, PG_META_CRYPTO_KEY, Logflare token, S3 protocol key และ MINIO_ROOT_PASSWORD ลงใน .env ณ เดือนตุลาคม 2026 สคริปต์จะเขียนค่าสุ่มสำหรับ POSTGRES_PASSWORD และ DASHBOARD_PASSWORD ด้วย สคริปต์นี้ต้องการ openssl ซึ่งมีอยู่แล้วใน Ubuntu image ปกติทั่วไป เนื่องจากปัจจุบันสคริปต์จะเขียนรหัสผ่านฐานข้อมูลใหม่ด้วย จึงควรเรียกใช้ด้วย --update-env ก่อนการเริ่มระบบครั้งแรกเท่านั้น ห้ามใช้กับ stack ที่มีข้อมูลอยู่แล้วโดยเด็ดขาด

มีสองค่าที่ควรตรวจสอบด้วยตนเองใน .env:

  • POSTGRES_PASSWORD: สคริปต์จะเติมค่าเลขฐานสิบหกแบบสุ่มซึ่งมีความปลอดภัย หากคุณต้องการแทนที่ด้วยค่าของคุณเอง ให้ใช้เฉพาะตัวอักษรและตัวเลขเท่านั้น เครื่องหมายวรรคตอนในส่วนนี้จะทำให้ connection string ที่บริการต่างๆ สร้างขึ้นจากการเชื่อมสตริงเกิดข้อผิดพลาด และความล้มเหลวจะแสดงออกมาในรูปแบบข้อผิดพลาดด้านการยืนยันตัวตน (authentication error) แทนที่จะเป็นข้อผิดพลาดในการแยกวิเคราะห์ (parsing error) ซึ่งจะทำให้ผู้ดูแลระบบหลงทางไปตรวจสอบในจุดที่ผิด
  • DASHBOARD_USERNAME และ DASHBOARD_PASSWORD: นี่คือข้อมูลประจำตัวสำหรับการยืนยันตัวตนพื้นฐาน (basic authentication) ของ Studio สคริปต์จะตั้งรหัสผ่านแบบสุ่มแต่ยังคงชื่อผู้ใช้ไว้ที่ค่าเริ่มต้นคือ supabase รหัสผ่านเริ่มต้นที่มากับระบบคือ this_password_is_insecure_and_should_be_updated ดังนั้นหากคุณข้ามขั้นตอนการใช้สคริปต์ไป ให้เปลี่ยนรหัสผ่านทันที

ทำความเข้าใจว่าเหตุใด ANON_KEY และ SERVICE_ROLE_KEY จึงไม่สามารถกำหนดขึ้นเองได้ ทั้งสองค่าคือ JWT ที่ลงนามด้วย JWT_SECRET ตัว gateway จะยอมรับเฉพาะ key ที่ตรงกันใน .env เท่านั้น และบริการที่อยู่เบื้องหลังจะตรวจสอบลายเซ็นเทียบกับ JWT_SECRET ดังนั้น key ที่ไม่ตรงกันจะถูกปฏิเสธด้วย HTTP 401 ตัว Envoy gateway เริ่มต้นจะตอบกลับด้วย 401 Unauthorized เช่นเดียวกับ Kong override ปัจจุบันที่รัน Kong 3.9 และส่งค่ากลับเป็น {"message":"Unauthorized"} การติดตั้งก่อนเดือนมีนาคม 2026 ที่รัน Kong 2.8 จะตอบกลับด้วย {"message":"Invalid authentication credentials"} นี่คือความล้มเหลวที่พบบ่อยที่สุดในการทำ self-hosting คือผู้ดูแลระบบเปลี่ยน JWT_SECRET แต่ยังคงใช้ demo key เดิมอยู่ ดังนั้นควรสร้างทั้งสามค่าพร้อมกันเสมอ

ให้ปฏิบัติต่อ SERVICE_ROLE_KEY เหมือนกับรหัสผ่าน root เพราะมันสามารถข้ามผ่านระบบความปลอดภัยระดับแถว (row level security) ได้ทั้งหมด ค่านี้ควรอยู่ในโค้ดฝั่งเซิร์ฟเวอร์เท่านั้น ห้ามนำไปไว้ที่อื่น

ตั้งค่า SITE_URL ให้เป็นที่อยู่ของแอปคุณ และตั้งค่า API_EXTERNAL_URL ให้เป็นที่อยู่สาธารณะของ API โดยมี /auth/v1 ต่อท้าย เช่น https://supabase.example.com/auth/v1 จากนั้นตั้งค่า SUPABASE_PUBLIC_URL ให้เป็นที่อยู่สาธารณะเดียวกันโดยไม่ต้องใส่ path ระบบ Auth จะสร้างลิงก์ยืนยันอีเมลและ OAuth callback จากค่าเหล่านี้ ดังนั้นหากปล่อยให้เป็นค่าเริ่มต้น localhost จะทำให้ผู้ใช้ทุกคนถูกส่งไปยังเครื่องของตนเองแทน

จากนั้นตรวจสอบสิ่งที่คุณมี:

sh run.sh secrets

เริ่มการทำงานและตรวจสอบสถานะความพร้อม

sh run.sh start
docker compose ps

run.sh start จะครอบ docker compose up -d --wait ไว้ ดังนั้นคำสั่งจะไม่ส่งค่ากลับจนกว่าการตรวจสอบความพร้อมจะเสร็จสิ้น บริการทุกตัวควรแสดงสถานะเป็น running (healthy) หรือ running การบูตครั้งแรกจะใช้เวลาประมาณ 2 ถึง 4 นาที เนื่องจาก Postgres ต้องรันสคริปต์เริ่มต้นก่อนที่บริการอื่นจะสามารถเชื่อมต่อได้

หากคอนเทนเนอร์มีการรีสตาร์ทตัวเอง ให้ตรวจสอบ log ตามชื่อบริการ:

docker compose logs db
docker compose logs auth

จากนั้น Studio จะพร้อมใช้งานที่พอร์ต 8000 โดยระบบจะเรียกให้คุณระบุชื่อผู้ใช้และรหัสผ่านสำหรับแดชบอร์ดที่คุณได้ตั้งค่าไว้

ห้ามเปิดพอร์ต 8000 สู่สาธารณะบนอินเทอร์เน็ต

Gateway ที่พอร์ต 8000 สื่อสารด้วย HTTP แบบปกติ ข้อมูล API key และรหัสผ่านของผู้ใช้ทุกคนจะถูกส่งผ่านเครือข่ายโดยไม่มีการเข้ารหัส ส่วนข้อมูลรับรองของ Studio ใช้การยืนยันตัวตนแบบ basic authentication ซึ่งเป็นการเข้ารหัสแบบ base64 ไม่ใช่การเข้ารหัสลับข้อมูล

ให้ติดตั้ง reverse proxy ไว้ด้านหน้า ทำการ terminate TLS (transport layer security) ที่จุดนั้น และกำหนดให้ gateway ฟังเฉพาะที่ loopback address เพื่อไม่ให้บุคคลภายนอกเข้าถึงได้ ใน docker-compose.yml บรรทัดพอร์ตภายใต้บริการ api-gw จะเปลี่ยนเป็น 127.0.0.1:${API_GW_HTTP_PORT:-${KONG_HTTP_PORT:-8000}}:8000/tcp และให้ proxy ส่งต่อคำขอไปยังพอร์ตดังกล่าว สำหรับการติดตั้งก่อนการเปลี่ยนไปใช้ Envoy ในเดือนสิงหาคม 2026 บรรทัดพอร์ตเดียวกันจะอยู่ภายใต้บริการที่ชื่อ kong แทน การใช้ Traefik หน้าแอป Compose หลายตัว ครอบคลุมรายละเอียดด้านใบรับรอง ส่วน proxy ตัวเดียวกันนี้จะทำหน้าที่เป็นหน้าด่านให้กับบริการอื่นทั้งหมดบนเครื่อง ตั้งแต่ stack นี้ไปจนถึงบริการอย่าง คลัง Jellyfin ที่ปรับแต่งให้เหมือนร้านวิดีโอในยุค 90 ซึ่งแต่ละบริการควรใช้ชื่อโฮสต์แทนการเปิดพอร์ตเพิ่ม หาก dashboard มีไว้สำหรับคุณใช้งานเพียงคนเดียว ให้ข้ามการใช้ proxy แล้วเข้าถึงพอร์ต loopback ผ่าน SSH tunnel แทน ซึ่งเป็นวิธีเดียวกับที่ open-kritt แบบ self-hosted ใช้เพื่อป้องกันไม่ให้หน้าจอการสแกนถูกเข้าถึงจากอินเทอร์เน็ตสาธารณะได้โดยสิ้นเชิง

นอกจากนี้ควรปิดพอร์ตที่เหลือที่ firewall ด้วย เนื่องจาก Docker จะเปิดพอร์ตโดยการเขียนกฎ iptables ของตัวเอง ซึ่งการตั้งค่า ufw แบบทั่วไปมองไม่เห็น กับดักนี้อธิบายไว้ใน เหตุใด Docker container จึงเพิกเฉยต่อกฎ ufw ของคุณ

สำรองข้อมูลฐานข้อมูล อย่าสำรองแค่ไดเรกทอรี

ข้อมูลของ Postgres อยู่ใน bind mount ที่ ./volumes/db/data การคัดลอกไดเรกทอรีดังกล่าวในขณะที่คอนเทนเนอร์กำลังทำงานจะทำให้ได้ข้อมูลที่ไม่สมบูรณ์ (torn copy) เนื่องจาก Postgres มีการบัฟเฟอร์การเขียนข้อมูล และไฟล์บนดิสก์จะมีความสอดคล้องกันก็ต่อเมื่อถึงจุด checkpoint เท่านั้น การกู้คืนข้อมูลจากวิธีนี้มักจะทำได้สำเร็จ แต่บางครั้งอาจทำให้ธุรกรรมล่าสุดสูญหายไปโดยที่คุณไม่รู้ตัว ซึ่งถือเป็นความล้มเหลวที่เลวร้ายที่สุดสำหรับการสำรองข้อมูล

ให้ใช้การ dump ข้อมูลแทน โดย pg_dumpall จะทำงานภายในคอนเทนเนอร์และสร้าง snapshot ที่มีความสอดคล้องกัน:

docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sql

ตรวจสอบให้แน่ใจว่าไฟล์ที่ได้ไม่มีขนาดเป็นศูนย์ก่อนที่จะนำไปใช้งาน จากนั้นให้ส่งไฟล์ dump เหล่านั้นออกจากเซิร์ฟเวอร์ตามกำหนดเวลา ซึ่งเป็นหน้าที่ของ การสำรองข้อมูลนอกสถานที่แบบเข้ารหัสด้วย restic การตั้งเวลา dump ข้อมูลที่ล้มเหลวโดยไม่มีการแจ้งเตือนนั้นไม่ต่างจากการไม่มีการสำรองข้อมูลเลย ดังนั้นควรตั้งค่า cron หรือ systemd job ให้ ส่งการแจ้งเตือนไปยังโทรศัพท์ของคุณ เมื่อการทำงานสิ้นสุดด้วยสถานะที่ไม่ใช่ศูนย์ และควรสำรองข้อมูล .env ไปพร้อมกันด้วย การสูญเสีย JWT_SECRET หมายความว่า token ที่ออกไปทั้งหมดจะใช้งานไม่ได้ และข้อมูลลับที่เข้ารหัสไว้ทั้งหมดจะไม่สามารถอ่านได้

ไฟล์ที่อัปโหลดจะถูกเก็บไว้ใน ./volumes/storage ซึ่งเป็นไฟล์ทั่วไป ดังนั้นการคัดลอกไฟล์โดยตรงจึงสามารถทำได้ตามปกติ

การอัปเดตโดยไม่สูญเสียข้อมูล

Supabase กำหนดเวอร์ชันของอิมเมจไว้ใน docker-compose.yml ดังนั้นเวอร์ชันจะไม่เปลี่ยนแปลงจนกว่าคุณจะดำเนินการเอง การกำหนดเวอร์ชัน (pinning) เป็นสิ่งที่ควรทำในทุก stack ที่คุณประกอบขึ้นเอง ซึ่งเป็นเหตุผลว่าทำไม การทำ self-hosted RustDesk relay จึงกำหนดเวอร์ชันของอิมเมจเซิร์ฟเวอร์ทั้งสองตัวไว้ แทนที่จะใช้แท็กที่เปลี่ยนแปลงได้ตามเวลา: การอัปเกรดควรเป็นสิ่งที่คุณเลือกทำในเวลาที่คุณพร้อมเสมอ ให้ทำการ dump ข้อมูลก่อนทุกครั้ง

docker compose pull
sh run.sh recreate

recreate จะหยุดการทำงานของ stack และเริ่มใหม่ด้วยอิมเมจเวอร์ชันใหม่ ข้อมูลของคุณจะยังคงอยู่เนื่องจากถูกเก็บไว้ใน bind mounts บนโฮสต์ ไม่ได้อยู่ภายในคอนเทนเนอร์ โปรดอ่าน CHANGELOG.md ใน repository ก่อนการอัปเกรดข้ามเวอร์ชันหลัก เนื่องจากกระบวนการอัปเกรดเวอร์ชันหลักของ Postgres เป็นขั้นตอนแยกต่างหากที่ recreate ไม่ได้ดำเนินการให้โดยอัตโนมัติ Postgres 17 เป็นค่าเริ่มต้นมาตั้งแต่เดือนมิถุนายน 2026 และการติดตั้งเดิมที่ใช้ Postgres 15 จะถูกย้ายไปยังเวอร์ชันใหม่ด้วย sudo bash utils/upgrade-pg17.sh ซึ่งใช้ pg_upgrade ในการย้ายข้อมูลในที่เดิมและจะขอการยืนยันในแต่ละขั้นตอนสำคัญ กระบวนการนี้ต้องการให้ทุกคอนเทนเนอร์ทำงานอยู่และต้องมีพื้นที่ว่างในดิสก์อย่างน้อยสองเท่าของขนาดฐานข้อมูลบวกกับอีก 5 GB และ Supabase ยังคงแนะนำให้คุณสำรองข้อมูลด้วยตนเองแยกต่างหากก่อนเริ่มดำเนินการ

หากต้องการนำการเปลี่ยนแปลงในไฟล์ Compose มาใช้ ให้รัน sh update.sh จากไดเรกทอรีของโปรเจกต์ หรือใช้ sh update.sh --dry-run เพื่อดูการเปลี่ยนแปลงที่จะเกิดขึ้นก่อน คำสั่งนี้จะรวมไฟล์จากต้นทางเข้ากับการแก้ไขของคุณ โดยจะไม่เขียนทับค่าเดิมที่มีอยู่ใน .env (จะเพิ่มเฉพาะคีย์ใหม่เท่านั้น) และจะเก็บสำรองการตั้งค่าของคุณไว้ใน backups/ ก่อนเขียนไฟล์ใหม่ แต่จะไม่รวมถึงฐานข้อมูล การติดตั้งที่ไม่มีไฟล์ .supabase-version จำเป็นต้องใช้ --from และ release ที่เริ่มใช้งานครั้งแรก ข้อมูลนี้มีความสำคัญอย่างยิ่งสำหรับ release เดือนสิงหาคม 2026 ซึ่งมีการเปลี่ยนบริการ kong เป็น api-gw และจำเป็นต้องมีการอัปเดต docker-compose.yml วิธีการแบบ manual ก็ยังคงใช้งานได้เช่นกัน: ให้ clone repository ต้นทางอีกครั้งแล้วคัดลอกไดเรกทอรี docker ทับโปรเจกต์ของคุณ โดยระมัดระวังไม่ให้เขียนทับไฟล์ .env

การรีเซ็ตแบบเต็มรูปแบบ ซึ่งจะทำลายทุกอย่างรวมถึงฐานข้อมูลและคืนค่า .env ให้เป็นค่าเริ่มต้น (ไฟล์เดิมจะถูกเก็บไว้ในชื่อ .env.old) เป็นสคริปต์แยกต่างหากและจะมีการขอการยืนยันก่อนดำเนินการ:

sh reset.sh

FAQ

ทำไมการเรียก API ของฉันถึงได้รับข้อความ "Invalid authentication credentials"?

ข้อความดังกล่าวมาจาก Kong 2.8 ซึ่งเป็น gateway ใน stack สำหรับการติดตั้งก่อนเดือนมีนาคม 2026 ส่วน Envoy gateway ที่เป็นค่าเริ่มต้นและ Kong รุ่นปัจจุบันที่รัน Kong 3.9 จะรายงานปัญหาเดียวกันนี้เป็น 401 Unauthorized ไม่ว่ากรณีใด คีย์ที่คุณส่งไปไม่ตรงกับ ANON_KEY หรือ SERVICE_ROLE_KEY ใน .env หรือคีย์เหล่านั้นไม่ได้ถูกลงนามด้วย JWT_SECRET ที่อยู่ใน .env ในขณะนี้ สำหรับ stack ที่ยังไม่เคยมีข้อมูล ให้สร้างคีย์ทั้งสามชุดใหม่พร้อมกันด้วย sh utils/generate-keys.sh --update-env สำหรับ stack ที่กำลังทำงานอยู่ ให้รันสคริปต์โดยไม่ต้องใช้ flag และตอบ no เพื่อให้ระบบแสดงค่าใหม่เพียงอย่างเดียว จากนั้นคัดลอก JWT_SECRET, ANON_KEY และ SERVICE_ROLE_KEY ไปใส่ใน .env ด้วยตนเอง และไม่ต้องแก้ไข POSTGRES_PASSWORD จากนั้นรัน sh run.sh recreate เพื่อให้ service อ่านค่าใหม่

ฉันสามารถรัน Supabase แบบ self-hosted บน VPS ขนาด 2 GB ได้หรือไม่?

ไม่สามารถรันได้อย่างเสถียร เอกสารการ self-host ของ Supabase ระบุว่า RAM ขนาด 4 GB คือขั้นต่ำ ณ เดือนตุลาคม 2026 และ stack ดังกล่าวใช้ RAM ประมาณ 3 GB ในช่วงเดือนกรกฎาคม 2026 จากการวัดผลที่รวมบริการ logging ซึ่งปัจจุบันเป็นแบบเลือกเปิดใช้งานได้ เครื่องขนาด 2 GB จะสูญเสีย container ไปเนื่องจาก out of memory killer และคุณจะพบ exit code 137 ใน docker compose ps ควรใช้ 8 GB สำหรับการใช้งานจริง และถือว่า 4 GB เป็นระดับต่ำสุดสำหรับการพัฒนาคนเดียว

Supabase แบบ self-hosted มี edge functions รวมอยู่ด้วยหรือไม่?

มี ไฟล์ Compose รวม runtime ของฟังก์ชันที่ใช้ Deno ไว้แล้ว และมันจะให้บริการทุกอย่างที่คุณวางไว้ภายใต้ ./volumes/functions อย่างไรก็ตาม มันไม่รวมเครือข่ายการปรับใช้ระดับโลกเหมือนแพลตฟอร์มที่โฮสต์ไว้ ดังนั้นฟังก์ชันของคุณจะรันบนเซิร์ฟเวอร์เครื่องเดียวของคุณ ในตำแหน่งเดียว

ฉันจะเชื่อมต่อกับฐานข้อมูล Postgres โดยตรงได้อย่างไร?

ใช้ docker exec -it supabase-db psql -U postgres สำหรับ interactive shell บนตัวเซิร์ฟเวอร์เอง สำหรับ client ภายนอก ให้เชื่อมต่อผ่าน Supavisor ที่พอร์ต 5432 ด้วยผู้ใช้ postgres.<POOLER_TENANT_ID> และ POSTGRES_PASSWORD ของคุณ อย่าเปิดพอร์ตดังกล่าวออกสู่สาธารณะ ให้เข้าถึงผ่าน VPN หรือ SSH tunnel

ทำไมอีเมลยืนยันการตรวจสอบสิทธิ์ของฉันถึงลิงก์ไปยัง localhost?

SITE_URL และ API_EXTERNAL_URL ใน .env ยังคงเป็นค่าเริ่มต้น บริการ auth จะสร้างลิงก์ยืนยันและรีเซ็ตรหัสผ่านทุกรายการจากค่าทั้งสองนี้ จึงส่งที่อยู่ที่ถูกกำหนดให้ส่งไป ให้ตั้งค่าทั้งสองรายการเป็น URL สาธารณะจริงของคุณและสร้าง stack ขึ้นมาใหม่

บทความนี้มีประโยชน์หรือไม่