סוכן קוד אומר שהפיצ'ר עובד. אולי זה נכון. הבדיקות שכתב עוברות, וזה מוכיח פחות ממה שכולם היו רוצים. מה שאתם באמת רוצים הוא לפתוח את זה בדפדפן לפני שזה מתקרב למשתמשים, ובלי לבקש מהסוכן לגעת בייצור.
סביבות תצוגה מקדימה פותרות את זה, ולא צריך לשם כך פלטפורמה. VPS אחד עם IPv4 משלו, Docker, Caddy ושני סקריפטים קצרים נותנים לכל ענף כתובת משלו כמו https://feature-login-form.preview.example.com, מאחורי סיסמה, ונבנים מחדש בכל push. הסוכן מקבל מפתח SSH שיכול להפעיל ולעצור תצוגות מקדימות ושום דבר אחר.
בנינו את זה על שרת בדיקות ועברנו על כל המחזור לפני שכתבנו: יצירה, פתיחה, push נוסף, פירוק, ניסיון לנצל את המפתח לרעה.
מה צריך
- VPS עם IPv4 ציבורי. על AI-Agent-IP נכנסות כמה תצוגות מקדימות בבת אחת.
- רשומת DNS מסוג wildcard:
*.preview.example.com← כתובת ה-IP של השרת. - מאגר האפליקציה שלכם עם
Dockerfileשמגיש בפורט 8080. כל שפה מתאימה. - Ubuntu 24.04 או Debian 12/13 עם
apt install -y docker.io caddy git.
שבטו את המאגר פעם אחת אל /srv/app עם מפתח פריסה לקריאה בלבד.
שני הסקריפטים
/usr/local/bin/preview-up בונה ענף ומעלה אותו לאוויר:
#!/usr/bin/env bash
# preview-up <branch> — build the branch and open it at https://<name>.preview.example.com
set -euo pipefail
BRANCH="$1"
NAME=$(printf '%s' "$BRANCH" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed 's/--*/-/g; s/^-//; s/-$//' | cut -c1-40)
DIR=/srv/previews/$NAME
git -C /srv/app fetch --quiet origin "$BRANCH"
rm -rf "$DIR"; git -C /srv/app worktree prune
git -C /srv/app worktree add --quiet --force --detach "$DIR" FETCH_HEAD
docker build --quiet -t "preview-$NAME" "$DIR" >/dev/null
docker rm -f "preview-$NAME" >/dev/null 2>&1 || true
docker run -d --name "preview-$NAME" --restart unless-stopped --memory 512m -p 127.0.0.1::8080 "preview-$NAME" >/dev/null
PORT=$(docker port "preview-$NAME" 8080/tcp | head -1 | awk -F: '{print $NF}')
cat > "/etc/caddy/previews/$NAME.caddy" <<CADDY
$NAME.preview.example.com {
import preview_common
reverse_proxy 127.0.0.1:$PORT
}
CADDY
systemctl reload caddy
echo "https://$NAME.preview.example.com"
/usr/local/bin/preview-down מסיר אותו:
#!/usr/bin/env bash
# preview-down <branch> — remove the branch preview
set -euo pipefail
NAME=$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed 's/--*/-/g; s/^-//; s/-$//' | cut -c1-40)
docker rm -f "preview-$NAME" >/dev/null 2>&1 || true
docker image rm "preview-$NAME" >/dev/null 2>&1 || true
rm -f "/etc/caddy/previews/$NAME.caddy"; rm -rf "/srv/previews/$NAME"; git -C /srv/app worktree prune
systemctl reload caddy
כמה בחירות כאן מכוונות. הקונטיינרים מפרסמים רק על 127.0.0.1 עם פורט אקראי, כך ששום דבר לא מגיע אליהם אלא דרך Caddy. זה חשוב, כי פורטים ש-Docker מפרסם עוקפים את ufw. לכל תצוגה מקדימה מגבלת זיכרון של 512 MB, כדי שענף אחד שיצא משליטה לא יפיל את האחרים. והרצה חוזרת של אותו ענף בונה אותו מחדש במקום: push, הרצת up, רענון.
Caddy: קובץ אחד לכל תצוגה מקדימה, סיסמה אחת לכולן
mkdir -p /etc/caddy/previews /srv/previews
chmod +x /usr/local/bin/preview-up /usr/local/bin/preview-down
caddy hash-password --plaintext 'choose-a-review-password'
הכניסו את ה-hash אל /etc/caddy/Caddyfile:
(preview_common) {
basicauth {
reviewer PASTE-THE-HASH-HERE
}
}
import /etc/caddy/previews/*.caddy
ואז systemctl reload caddy. עכשיו כל תצוגה מקדימה נמצאת מאחורי אותה התחברות, כך שענף חצי גמור עם פלט דיבאג לא עומד חשוף באינטרנט. בגרסאות חדשות של Caddy ההנחיה נכתבת גם basic_auth; basicauth עדיין עובד בשתיהן.
המפתח של הסוכן: up ו-down, לא יותר
הסוכן צריך להפעיל תצוגות מקדימות, לא להיות הבעלים של השרת. צרו משתמש deploy וסקריפט שער שמקבל בדיוק שתי פקודות:
#!/usr/bin/env bash
# /usr/local/bin/preview-gate — the only thing the agent's key may run
set -euo pipefail
read -r ACTION BRANCH EXTRA <<< "${SSH_ORIGINAL_COMMAND:-}"
[[ -z "${EXTRA:-}" && "${BRANCH:-}" =~ ^[A-Za-z0-9][A-Za-z0-9._/-]{0,99}$ && "$BRANCH" != *..* ]] || { echo "usage: up|down <branch>" >&2; exit 2; }
case "$ACTION" in
up) exec sudo /usr/local/bin/preview-up "$BRANCH" ;;
down) exec sudo /usr/local/bin/preview-down "$BRANCH" ;;
*) echo "usage: up|down <branch>" >&2; exit 2 ;;
esac
useradd -m -s /bin/bash deploy
echo 'deploy ALL=(root) NOPASSWD: /usr/local/bin/preview-up, /usr/local/bin/preview-down' > /etc/sudoers.d/preview
chmod 440 /etc/sudoers.d/preview && visudo -cf /etc/sudoers.d/preview
chmod 755 /usr/local/bin/preview-gate
ב-/home/deploy/.ssh/authorized_keys, קשרו את המפתח הציבורי של הסוכן לסקריפט הזה:
restrict,command="/usr/local/bin/preview-gate" ssh-ed25519 AAAA... coding-agent
מהמכונה שבה הסוכן עובד:
ssh deploy@preview.example.com up feature/login-form
# https://feature-login-form.preview.example.com
ssh deploy@preview.example.com down feature/login-form
בבדיקה שלנו up בנה ופרסם את הענף, up שני אחרי commit חדש הגיש את הגרסה החדשה, ו-down הסיר את הקונטיינר ואת האתר. ניסיונות של cat /etc/shadow, up x; id, שמות ענפים כמו -x או a/../b, או התחברות אינטראקטיבית עם המפתח קיבלו כולם רק usage: up|down <branch>. שם ענף חייב להתחיל באות או בספרה ואינו יכול להכיל ...
חיבור לסוכן
ב-Claude Code או ב-Codex מספיקה שורה אחת בקובץ ההנחיות של הפרויקט:
אחרי push של ענף, הרץ
ssh deploy@preview.example.com up <branch>והכנס את הכתובת שהודפסה לסיכום שלך. הרץdownכשהענף מוזג או ננטש.
אם ה-CI שלכם כבר רץ בכל push, קראו לאותה פקודה משם והרחיקו את המפתח לגמרי מסביבת הסוכן. זו האפשרות המחמירה יותר, ואנחנו היינו בוחרים בה לכל דבר שמעבר לפרויקט אישי.
למה לשים לב
- דיסק. כל בנייה משאירה שכבות אימג'. cron שבועי עם
docker image prune -fשומר על זה בשליטה; downכבר מוחק את האימג' של התצוגה המקדימה עצמה. - ענפים שאף אחד לא סוגר. סוכנים פותחים יותר ענפים מבני אדם. משימת cron שמונה קונטיינרים
preview-*ישנים משבוע ומריצה עליהםpreview-downחוסכת לכם עשרים תצוגות מקדימות נשכחות. - סודות. תצוגות מקדימות צריכות לרוץ עם פרטי גישה לבדיקות. סיסמת ה-basic auth מרחיקה זרים, אבל היא לא הופכת לגיטימי לחבר תצוגה מקדימה למסד הנתונים של הייצור.
- זמן בנייה. אימג'ים נבנים על השרת, כך שבנייה כבדה מתחרה על CPU עם התצוגות המקדימות שרצות. אם בנייה לוקחת דקות, בנו ב-CI ומשכו את האימג'.
הסוכן עצמו לא חייב לגור על השרת הזה. אם הוא גר עליו, ראו VPS ל-Claude Code, וכדי לתת לו להזמין ולתחזק את השרת בעצמו, חברו אותו לשרת ה-MCP של EQVPS. אותה מכונה יכולה לארח גם את שער ה-MCP של הצוות. להרצת קוד לא אמין בלי שום שרת יש ארגזי חול, והתוכניות עם IPv4 משלהן מתחילות ב-$8 לחודש.
תגובות
אין עדיין תגובות. היו הראשונים.