האפליקציה שלכם עובדת ב-localhost. עכשיו אתם רוצים לשתף אותה דרך דומיין אמיתי, בלי להשאיר את המחשב הנייד דלוק. החלקים החסרים הם VPS, תהליך אפליקציה מנוהל, DNS ופרוקסי הפוך (reverse proxy) עם HTTPS.
במדריך הזה נלמד לעשות זאת עם אפליקציית Node.js קטנה. Claude Code יכול לעזור לבדוק את הפרויקט שלכם ולהכין הגדרות לבדיקה; האחריות לשינויים בשרת נשארת בידיכם. המודל אינו מותקן על ה-VPS, והגישה ל-Claude והחיוב עליה נפרדים מהאחסון.
הדרכה מונפשת. לוח הבקרה הוא הדגמה בדיונית ואינו ניטור תשתית חי.
צפו בסקירת הפריסה
צפו בסקירת הפריסה (סרטון באנגלית).
מה בדקנו בפועל: לוח בקרה אמיתי שנוצר במקור על ידי Claude Code נפרס בידי המפעיל שלנו על VPS זמני של Linux. אימתנו DNS ציבורי, HTTPS מהימן, הפניה מ-HTTP ל-HTTPS, תהליכי אפליקציה ופרוקסי שאינם רצים כ-root, וגישה לאחר הפעלה מחדש של שירות האפליקציה. לא בוצעה ריצת פריסה אוטונומית חדשה של Claude. ההנחיה המוצעת להלן היא להדגמה בלבד ואינה תגובה מוקלטת.
לפני שמתחילים
- VPS של Linux עם systemd וחשבון SSH עם גישת sudo. השתמשו תחילה ב-VPS לבדיקות; אל תדרסו שירותים או הגדרות web של אתר קיים.
- סביבת ריצה נתמכת של Node.js LTS מותקנת בשרת, ו-Caddy מותקן כשירות מערכת. התקינו את דרישות הקדם האלה לפני שתבצעו את שלבי הפריסה.
- דומיין או תת-דומיין שאתם יכולים לערוך את רשומות ה-DNS שלו.
- אפליקציה קטנה ועצמאית. הדוגמה שלנו מגישה את
index.htmlבאמצעותserver.mjs, ללא תלויות בחבילות וללא מסד נתונים.
אפליקציות מבוססות framework זקוקות לפקודת build, לפקודת הפעלה, לתלויות ולתוכנית אחסון משלהן. אל תניחו שפרויקט Next.js, Python או פרויקט מבוסס מסד נתונים יכול להשתמש בדוגמה הזו בת שני הקבצים ללא שינוי.
1. בקשו מ-Claude Code לבדוק את הפרויקט לפני שמשנים בו משהו
התחילו בתיקיית הפרויקט המקומית שלכם. בקשה ראשונה שימושית היא:
Inspect this project without changing files. Identify its runtime,
build and start commands, configuration and secrets. Propose a Linux
VPS deployment using a non-root systemd service and Caddy HTTPS.
Bind the app to 127.0.0.1:3000. Explain each proposed file and
verification step. Do not connect to a server or edit DNS.
זרימות העבודה המתועדות של Claude Code כוללות תכנון לפני עריכה. עברו על השינויים המוצעים במקום לקבל פקודות פריסה בעיניים עצומות. הרחיקו מפתחות API, פרטי גישה לפרודקשן ומפתחות SSH פרטיים מההנחיות ומהמאגרים; גישת קריאה בלבד אינה הופכת קבצים רגישים לחסויים.
2. הכינו והעבירו את האפליקציה
לדוגמה המינימלית המדויקת הזו, שמרו את ה-HTML שלכם בשם index.html והשתמשו בשרת הבא. הוא נקשר כברירת מחדל ל-loopback ואינו חושף קבצי פרויקט שרירותיים:
import {createServer} from 'node:http';
import {readFileSync} from 'node:fs';
import {fileURLToPath} from 'node:url';
const page=readFileSync(new URL('./index.html',import.meta.url));
export function createAppServer(){
return createServer((req,res)=>{
const pathname=new URL(req.url,'http://localhost').pathname;
if(pathname!=='/' && pathname!=='/index.html'){
res.writeHead(404,{'Content-Type':'text/plain; charset=utf-8'});res.end('Not found');return;
}
res.writeHead(200,{'Content-Type':'text/html; charset=utf-8','X-Content-Type-Options':'nosniff'});res.end(page);
});
}
if(process.argv[1]===fileURLToPath(import.meta.url)){
const host=process.env.HOST||'127.0.0.1';const port=Number(process.env.PORT||3000);
const server=createAppServer();server.listen(port,host,()=>console.log(`Demo app listening on ${host}:${port}`));
process.on('SIGTERM',()=>server.close(()=>process.exit(0)));
}
הריצו אותו מקומית באמצעות node server.mjs, פתחו את http://127.0.0.1:3000, ואז עצרו אותו לפני שתמשיכו. ב-VPS שכבר משתמש בפורט 3000, בחרו פורט פרטי אחר באופן עקבי הן בשירות והן בפרוקסי.
מתיקיית הפרויקט המקומית שלכם, החליפו את deploy ו-VPS_IP בחשבון ה-SSH שלכם ובכתובת השרת בפועל:
ssh deploy@VPS_IP 'mkdir -p ~/my-app'
scp index.html server.mjs deploy@VPS_IP:~/my-app/
בשרת, התקינו את שני הקבצים הלא-סודיים האלה בתיקיית אפליקציה קריאה:
sudo install -d -m 0755 /opt/my-app
sudo install -m 0644 ~/my-app/index.html ~/my-app/server.mjs /opt/my-app/
command -v node
רשמו את הנתיב המוחלט של קובץ ההרצה של Node. הוא חייב להיות נגיש מחוץ ל-shell של ההתחברות ומחוץ לתיקיית הבית שלכם. התקנה של מנהל גרסאות למשתמש בלבד תחת /home אינה מתאימה לשירות המחוזק שלהלן. לעולם אל תעתיקו קובץ .env של פיתוח, מפתח פרטי או גיבוי של מסד נתונים לתיקיית web ציבורית.
3. הריצו את האפליקציה כשירות systemd ללא root
השתמשו ב-sudoedit /etc/systemd/system/my-app.service. החליפו את /ABSOLUTE/PATH/TO/node בנתיב האמיתי של קובץ ההרצה ברמת השרת שבדקתם זה עתה:
[Unit]
Description=My Node web app
After=network.target
[Service]
Type=simple
DynamicUser=true
WorkingDirectory=/opt/my-app
ExecStart=/ABSOLUTE/PATH/TO/node /opt/my-app/server.mjs
Environment=NODE_ENV=production
Environment=HOST=127.0.0.1
Environment=PORT=3000
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.target
בקרות הביצוע של systemd מתעדות את החשבון הדינמי ואת הגדרות החיזוק. פרופיל זה מתאים לאפליקציית הקריאה בלבד שלנו; אפליקציות שכותבות העלאות או מסדי נתונים דורשות אחסון קבוע והרשאות שהוגדרו במכוון.
sudo systemctl daemon-reload
sudo systemctl enable --now my-app.service
sudo systemctl status my-app.service --no-pager
curl -fsS http://127.0.0.1:3000/
פתרו שגיאות אפליקציה לפני שאתם נוגעים ב-DNS. שירות שהופעל (enabled) מוגדר להתחיל באתחול, אבל זו אינה הוכחה לכך שנערכה בדיקת אתחול מחדש.
4. כוונו תת-דומיין אל ה-VPS
צרו רשומת A עבור שם המארח שבחרתם, כמו app.example.com, שמכוונת לכתובת ה-IPv4 הציבורית של ה-VPS שלכם. עם Cloudflare, הדגמת השרת הישירה שלנו השתמשה ב-DNS only וב-TTL אוטומטי. אל תעתיקו את כתובת ה-IP של ההדגמה שלנו לרשומות של האתר שלכם.
בדקו את התשובה הציבורית באמצעות dig +short A app.example.com. בדקו גם את dig +short AAAA app.example.com: אם קיימת רשומת IPv6, היא חייבת להגיע לאותה פריסה תקינה גם דרך IPv6. DNS רק ממפה כתובת; הוא אינו מפעיל את האפליקציה ואינו מגדיר HTTPS.
5. הציבו את Caddy לפני האפליקציה הפרטית
השאירו את שירות Node על 127.0.0.1:3000. ודאו שפורטי ה-web הציבוריים 80 ו-443 נגישים דרך חומת האש של הספק וחומת האש של המארח, בלי להסיר את גישת ה-SSH שלכם. אל תחשפו את פורט 3000 לאינטרנט.
הוסיפו את בלוק האתר הזה להגדרות שירות Caddy המותקן שלכם, והחליפו את שם המארח לדוגמה. שמרו על בלוקי אתר אחרים שאינם קשורים:
app.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}
ההנחיה reverse_proxy מעבירה בקשות ציבוריות לאפליקציה הפרטית. עם שם מארח ציבורי מתאים ותנאי אימות תעודות תקינים, ה-HTTPS האוטומטי של Caddy משיג ומחדש תעודות ומפנה מ-HTTP ל-HTTPS.
עבור שירות המערכת הסטנדרטי של Caddy ונתיב ההגדרות הסטנדרטי:
sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddy
ה-VPS שבו צילמנו השתמש בשירות Caddy ייעודי ובנתיבי הגדרות מבודדים ולא בשירות המשותף הסטנדרטי שלמעלה. עקרון הניתוב זהה; הנתיבים ושמות השירותים הפונים לקורא הם התאמות, ולא תמלול מילולי של התקנה.
6. אמתו את התוצאה הציבורית ואת הפעלת השירות מחדש
curl -I http://app.example.com/
curl -I https://app.example.com/
sudo systemctl restart my-app.service
curl --retry 5 --retry-delay 1 --retry-connrefused -I https://app.example.com/
בדקו הפניית HTTP ל-HTTPS, תגובת HTTPS מוצלחת ותעודה תקפה בדפדפן. אל תשתמשו ב-curl -k כדי להסתיר שגיאות אמון. פתחו את הדף מרשת אחרת, ולא רק מתוך ה-VPS.
בדיקת הפעלה מחדש שנכשלה דורשת בירור: בדקו את journalctl -u my-app.service -n 50 --no-pager ואת הלוגים של שירות Caddy. שגיאות DNS, IPv6 שגוי, אפליקציה שנעצרה, פורט upstream שגוי ואימות תעודה חסום הן בעיות שונות.
אימתנו הפעלה מחדש של שירות האפליקציה, ולא אתחול מחדש של ה-VPS או הגדרת זמינות גבוהה. לפני שמארחים אפליקציה עסקית אמיתית, תכננו גם עדכונים, גיבויים, ניטור, ניהול סודות וכל נתונים קבועים.
מפרויקט מקומי לכתובת ציבורית
הדרך השלמה פשוטה: הכינו את הפרויקט, העבירו אותו ל-VPS, השאירו אותו רץ כשירות מנוהל ללא root, כוונו את ה-DNS לשרת וסיימו את ה-HTTPS הציבורי בפרוקסי ההפוך. Claude Code יכול לעזור להכין ולהסביר את החלקים האלה; בדיקה ובקרות תפעוליות עדיין חשובות.
עיינו בחבילות ה-VPS של Linux של SharpHeberg כשתהיו מוכנים להעלות פרויקט מקומי לאוויר.
האחסון מספק את סביבת השרת, ולא כולל מנוי Claude או מודל Claude המאוחסן מקומית.