איך לארח את Supabase בעצמכם ב-VPS עם Docker
מדריך להפעלת מחסנית Supabase הרשמית ב-Docker: אילו סודות להחליף, מה עושים 14 השירותים, כמה RAM נדרש, ואיך מגבים ומעדכנים בלי לאבד נתונים.
מה אתם בונים
אירוח עצמי של Supabase פירושו להפעיל בשרת שלכם את מחסנית Docker Compose הרשמית: Postgres, ממשק REST מולו, שירות אימות, אחסון קבצים, WebSockets לעדכונים בזמן אמת ולוח הבקרה Studio. משכפלים מאגר אחד, עורכים קובץ .env אחד ומפעילים כ-14 קונטיינרים, שפועלים יחד כמו פרויקט Supabase שנמצא בשליטתכם.
ההתקנה קצרה. הבעיה העיקרית נגרמת מקובץ .env. הקובץ מגיע עם סודות הדגמה שפורסמו במאגר, ומחסנית שמופעלת עם ערכי ברירת המחדל האלה פתוחה לכל מי שמאתר אותה. המדריך מסביר אילו סודות חובה להחליף, מה התפקיד של כל שירות, כמה זיכרון המחסנית באמת צריכה וכיצד לעדכן אותה בלי למחוק את מסד הנתונים.
אם Compose חדש לכם, קראו תחילה את יסודות Docker Compose ב-VPS. כל האמור בהמשך מניח שהפקודה docker compose version כבר מציגה גרסה.
מה stack בפועל מכיל
Supabase אינה תוכנית אחת. קובץ Compose מפעיל קבוצה של שירותים נפרדים באותה רשת. הכרת התפקיד של כל שירות הופכת רשימה ארוכה של שמות containers למערכת שאפשר לנפות בה תקלות.
dbהוא PostgreSQL עם הרחבות Supabase שנטענו. כל שאר השירותים מתקשרים איתו. אם ה-container הזה אינו תקין, גם כל השאר נכשלים.kongהוא API gateway. הוא מאזין ב-port 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 שמאחוריו.analytics(Logflare) ו-vectorאוספים logs, ו-supavisorהוא מאגר חיבורי PostgreSQL.
זו הסיבה שמספרי המשאבים בהמשך הם כפי שהם. אינכם מפעילים מסד נתונים בלבד. אתם מפעילים מסד נתונים ולצדו תריסר שירותי תמיכה.
תכנון משאבים: תכננו 8 GB של RAM
המחסנית צורכת במצב סרק כ-2.5 עד 3 GB של זיכרון תושב בהתקנה חדשה, נכון ליולי 2026, עוד לפני הנתונים או התעבורה שלכם. שירות ניתוח הנתונים והתהליך Studio Node.js הם שני הצרכנים הגדולים ביותר בנפרד. שרת עם 2 GB יפעיל את ה-containers, ולאחר מכן הליבה תפסיק אחד מהם באמצעות מנגנון סיום התהליכים עקב מחסור בזיכרון, בדרך כלל analytics או db. התסמין הוא container שנתקע בלולאת אתחולים עם קוד יציאה 137.
הקצו 8 GB של RAM ו-4 vCPU לכל מערכת שאתם מסתמכים עליה. 4 GB מספיקים למופע פיתוח אישי, אם אתם מקבלים זאת ששאילתה כבדה ומופע Studio הפועלים בו-זמנית יהיו איטיים. גם שטח האחסון חשוב, מכיוון ש-Postgres, אמצעי האחסון ונתוני היומן נמצאים כולם תחת ספריית הפרויקט. התחילו עם 40 GB ועקבו אחר הצריכה.
התקנה: שכפול המאגר הרשמי
הדרך הנתמכת מעתיקה את ספריית docker מהמאגר הראשי אל ספריית פרויקט שבבעלותכם. ההפרדה הזו חשובה, משום שהיא מונעת מ-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 pulldocker compose pull מוריד כמה גיגה-בייט של images. הפעולה אמורה להסתיים כאשר כל השירותים מסומנים כ-Pulled. שגיאת manifest unknown בשלב זה פירושה שתגית ה-image המקובעת הוסרה במעלה הזרם. הפתרון הוא למשוך עותק חדש יותר של המאגר, ולא לערוך את התגיות ידנית.
הסודות שעליך לשנות לפני ההפעלה הראשונה
בצע זאת לפני הפעלת ה-stack, ולא לאחר מכן. כמה מהערכים האלה נכתבים בנתונים בעת האתחול הראשון, ולכן שינוי שלהם בהמשך מחייב איפוס של מסד הנתונים.
ה-repository כולל מחולל שמפיק את כל הערכים כראוי, כולל שני מפתחות ה-API שיש לחתום באמצעות סוד ה-JWT החדש שלך.
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 אל .env. הוא זקוק ל-openssl, שקיים בכל image רגיל של Ubuntu.
שני ערכים הוא אינו מגדיר, ועליך לערוך אותם ידנית ב-.env:
POSTGRES_PASSWORD. השתמש באותיות ובספרות בלבד. סימני פיסוק כאן שוברים את מחרוזות החיבור שכמה שירותים בונים באמצעות שרשור מחרוזות. הכשל נראה כמו שגיאת אימות ולא כמו שגיאת ניתוח, ולכן החיפוש מתבצע במקום הלא נכון.DASHBOARD_USERNAMEו-DASHBOARD_PASSWORD. אלה פרטי האימות הבסיסי עבור Studio. סיסמת ברירת המחדל שסופקה היא ממשthis_password_is_insecure_and_should_be_updated.
חשוב להבין מדוע אי אפשר להמציא את ANON_KEY ואת SERVICE_ROLE_KEY. שניהם JWTs שנחתמו באמצעות JWT_SECRET. ה-gateway מאמת את החתימה הזו בכל בקשה, ולכן מפתח שאינו תואם לסוד שלך נדחה עם {"message":"Invalid authentication credentials"}. זהו הכשל הנפוץ ביותר באירוח עצמי: המפעיל שינה את JWT_SECRET אך השאיר את מפתחות ההדגמה. הפק את שלושתם יחד, תמיד.
התייחס ל-SERVICE_ROLE_KEY כמו לסיסמת root. הוא עוקף לחלוטין את אבטחת רמת השורה. מקומו הוא בקוד בצד השרת בלבד, ולא בשום מקום אחר.
הגדר את SITE_URL ואת API_EXTERNAL_URL לכתובת שאליה המשתמשים שלך ייגשו בפועל, לדוגמה https://supabase.example.com. Auth בונה מערכי קישורים לאישור דוא"ל ול-callback של OAuth מתוך הערכים האלה, ולכן השארתם כ-http://localhost:8000 מפנה כל אחד מהמשתמשים שלך אל המחשב שלו.
לאחר מכן בדוק את הערכים שהגדרת:
sh run.sh secretsהפעלת המערכת ואימות תקינותה
sh run.sh start
docker compose psrun.sh start עוטף את docker compose up -d --wait, ולכן הוא אינו מחזיר את השליטה עד שבדיקות התקינות עוברות. כל שירות אמור להציג running (healthy) או running. ההפעלה הראשונה נמשכת בין שתי דקות לארבע דקות, מכיוון ש-Postgres מריץ את סקריפטי האתחול שלו לפני שכל רכיב אחר יכול להתחבר.
אם container מופעל מחדש, קראו את הלוגים שלו לפי שם השירות:
docker compose logs db
docker compose logs authStudio זמין כעת בפורט 8000, והוא יבקש את שם המשתמש והסיסמה ללוח הבקרה שהגדרתם.
אין לחשוף את פורט 8000 לאינטרנט הציבורי
Kong בפורט 8000 מדבר ב-HTTP רגיל. כל מפתח API וכל סיסמת משתמש עוברים ברשת כטקסט גלוי. פרטי הכניסה ל-Studio משתמשים גם באימות בסיסי, שהוא קידוד base64 ולא הצפנה.
הציבו לפניו פרוקסי הפוך, סיימו בו את TLS (אבטחת שכבת התעבורה), וקשרו את Kong לכתובת loopback כדי ששום גורם אחר לא יוכל לגשת אליו. בתוך docker-compose.yml מיפוי הפורטים kong הופך ל-127.0.0.1:8000:8000, והפרוקסי מעביר אליו את התעבורה. Traefik לפני כמה יישומי Compose מסביר את נושא האישורים.
סגרו גם את שאר הפורטים בחומת האש, משום ש-Docker מפרסם פורטים באמצעות כתיבת כללי iptables משלו, והגדרת ufw נאיבית אינה רואה אותם. המלכודת הזו מוסברת ב-מדוע קונטיינרים של Docker מתעלמים מכללי ufw שלכם.
גבה את מסד הנתונים, לא את הספרייה
נתוני Postgres נמצאים ב-bind mount ב-./volumes/db/data. העתקת הספרייה בזמן שהמכולה פועלת יוצרת עותק חלקי, משום ש-Postgres מאחסן כתיבות במאגר, והקבצים בדיסק עקביים רק בנקודת ביקורת. שחזור מהעותק הזה בדרך כלל יצליח, אך לעיתים יאבד בשקט את העסקאות האחרונות. זהו מצב הכשל החמור ביותר האפשרי בגיבוי.
במקום זאת, הפק dump. הפקודה pg_dumpall פועלת בתוך המכולה ויוצרת תמונת מצב עקבית:
docker exec -t supabase-db pg_dumpall -U postgres > supabase-$(date +%F).sqlודא שהקובץ אינו ריק לפני שאתה מסתמך עליו. לאחר מכן העבר את קובצי ה-dump אל מחוץ לשרת לפי לוח זמנים. לשם כך נועדו גיבויים מוצפנים מחוץ לאתר באמצעות restic. גבה באותו זמן גם את .env. אובדן של JWT_SECRET יגרום לכל האסימונים שהונפקו להפוך לבלתי תקפים, ולכל הסודות המוצפנים המאוחסנים להפוך לבלתי ניתנים לקריאה.
קבצים שהועלו נמצאים ב-./volumes/storage. אלה קבצים רגילים, ולכן העתקה פשוטה מספיקה.
עדכון בלי לאבד נתונים
Supabase מקבעת את גרסאות ה-images ב-docker-compose.yml, ולכן שום דבר אינו משתנה עד שמבצעים עדכון. יש ליצור dump לפני כל עדכון, ללא יוצא מן הכלל.
docker compose pull
sh run.sh recreaterecreate עוצרת את ה-stack ומפעילה אותו מחדש באמצעות ה-images החדשים. הנתונים נשמרים, משום שהם נמצאים ב-bind mounts במארח ולא בתוך ה-containers. יש לקרוא את CHANGELOG.md במאגר לפני מעבר לגרסה ראשית חדשה, מכיוון ששדרוגים ראשיים של Postgres אינם מתבצעים אוטומטית ודורשים dump ו-restore.
כדי להחיל שינויים בקובץ Compose עצמו, יש לשכפל שוב את המאגר upstream ולהעתיק את ספריית docker שלו אל הפרויקט, תוך הקפדה שלא להחליף את .env.
האיפוס המלא, שמשמיד הכול כולל את מסד הנתונים, מתבצע באמצעות סקריפט נפרד והוא מבקש אישור:
sh reset.shFAQ
מדוע קריאות ה-API שלי מחזירות "Invalid authentication credentials"?
ה-ANON_KEY או ה-SERVICE_ROLE_KEY שלך לא נחתם באמצעות ה-JWT_SECRET שמוגדר כעת ב-.env. ה-gateway מאמת את החתימה בכל בקשה ודוחה אי-התאמה. צור מחדש את שלושת הערכים יחד באמצעות sh utils/generate-keys.sh --update-env, ולאחר מכן הרץ את sh run.sh recreate כדי שהשירותים יקראו את הערכים החדשים.
האם ניתן להריץ Supabase באירוח עצמי על VPS בנפח 2 GB?
לא באופן אמין. נכון ל-July 2026, המחסנית צורכת בעת חוסר פעילות כמעט 3 GB, מכיוון שהיא מפעילה כ-14 שירותים. לכן שרת בנפח 2 GB מאבד containers ל-oom killer, וב-docker compose ps מופיע exit code 137. השתמש ב-8 GB בסביבת production, והתייחס ל-4 GB כדרישת המינימום לפיתוח עצמאי.
האם Supabase באירוח עצמי כולל edge functions?
כן. קובץ ה-Compose כולל runtime לפונקציות המבוסס על Deno, והוא משרת כל דבר שתציב תחת ./volumes/functions. הוא אינו כולל את רשת הפריסה הגלובלית של הפלטפורמה המתארחת. לכן הפונקציות שלך פועלות בשרת היחיד שלך ובמיקום יחיד.
כיצד מתחברים ישירות למסד הנתונים Postgres?
השתמש ב-docker exec -it supabase-db psql -U postgres כדי לפתוח מעטפת אינטראקטיבית בשרת עצמו. עבור לקוח חיצוני, התחבר דרך Supavisor ביציאה 5432 באמצעות המשתמש postgres.<POOLER_TENANT_ID> וה-POSTGRES_PASSWORD שלך. אל תפתח את היציאה הזו לאינטרנט. גש אליה דרך VPN או מנהרת SSH.
מדוע קישורי האישור בהודעות הדוא"ל של האימות שלי הפנו ל-localhost?
ה-SITE_URL וה-API_EXTERNAL_URL ב-.env נשארו בערכי ברירת המחדל שלהם. שירות האימות בונה כל קישור אישור ואיפוס סיסמה משני הערכים האלה, ולכן הוא שולח את הכתובת שהוגדרה לו. הגדר את שניהם לכתובת הציבורית האמיתית שלך וצור מחדש את המחסנית.