−25%

Windows-ის წლიურ გადახდაზე, 31 ოქტომბრამდე. ტარიფებზე

EQVPS
დაწყება

VPS coding აგენტების პრევიუებისთვის: აგენტის მიერ გაგზავნილი ყოველი ტოტი საკუთარ მისამართს იღებს

Coding აგენტმა ტოტი დაასრულა და ამბობს, რომ ყველაფერი მუშაობს. მიეცით სერვერი, სადაც ამის შემოწმება შეიძლება: ყოველი ტოტი კონტეინერში იკრიბება და საკუთარ HTTPS ქვედომენზე პაროლის მიღმა იხსნება, აგენტის SSH გასაღებს კი მხოლოდ პრევიუების გაშვება და გაჩერება შეუძლია.

Coding აგენტი ამბობს, რომ ფუნქცია მუშაობს. შეიძლება ასეც არის. მის მიერ დაწერილი ტესტები გადის, და ეს იმაზე ნაკლებს ამტკიცებს, ვიდრე ყველას გვინდოდა. სინამდვილეში გინდათ შედეგი ბრაუზერში გახსნათ, სანამ მომხმარებლებთან მიახლოვდება, და ეს ისე, რომ აგენტს პროდაქშენის შეხება არ სთხოვოთ.

ამას პრევიუ-გარემოები წყვეტს და პლატფორმა მათთვის საჭირო არ არის. ერთი VPS საკუთარი IPv4-ით, Docker, Caddy და ორი მოკლე სკრიპტი ყოველ ტოტს საკუთარ მისამართს აძლევს, მაგალითად https://feature-login-form.preview.example.com, პაროლის მიღმა და ყოველ push-ზე თავიდან აწყობით. აგენტი იღებს SSH გასაღებს, რომელსაც პრევიუების გაშვება და გაჩერება შეუძლია და მეტი არაფერი.

ეს სატესტო სერვერზე ავაწყვეთ და მთელი ციკლი გავიარეთ, სანამ აღვწერდით: შექმნა, გახსნა, თავიდან push, მოხსნა, გასაღების ბოროტად გამოყენების ცდა.

რა არის საჭირო

  • VPS საჯარო IPv4-ით. AI-Agent-IP-ზე რამდენიმე პრევიუ ერთდროულად ეტევა.
  • wildcard DNS ჩანაწერი: *.preview.example.com → სერვერის IP.
  • თქვენი აპლიკაციის რეპოზიტორია Dockerfile-ით, რომელიც 8080 პორტზე მუშაობს. ენას მნიშვნელობა არ აქვს.
  • Ubuntu 24.04 ან Debian 12/13 apt install -y docker.io caddy git-ით.

ერთხელ დააკლონეთ რეპოზიტორია /srv/app-ში მხოლოდ წაკითხვის უფლების მქონე deploy გასაღებით.

ორი სკრიპტი

/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'

ჩასვით ჰეში /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-მა ტოტი ააწყო და გამოაქვეყნა, ახალი commit-ის შემდეგ მეორე up-მა ახალი ვერსია მოგვცა, 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-ისთვის, ხოლო იმისთვის, რომ ეს სერვერი თავად შეუკვეთოს და მოუაროს, დააკავშირეთ EQVPS-ის MCP სერვერს. იმავე მანქანაზე შეიძლება თქვენი გუნდის MCP კარიბჭეც იყოს. არასანდო კოდისთვის სერვერის გარეშე არსებობს sandbox-ები, ხოლო საკუთარი IPv4-ის მქონე ტარიფები თვეში $8-დან იწყება.

ხდკ

რატომ არ უნდა მივცეთ აგენტს პირდაპირ პროდაქშენში დეპლოის უფლება?

რადგან „ტესტები გადის“ და „მუშაობს“ ერთი და იგივე არ არის, და ამის გადაწყვეტა აგენტმა ბოლოს უნდა შეძლოს. პრევიუ ადამიანს აძლევს რამეს, რაზეც დააწკაპუნოს, სანამ რაიმე მომხმარებლებამდე მივა, ერთი დამატებითი ბრძანების ფასად.

რომელი ტარიფი გამოდგება?

დამოკიდებულია, რამდენი პრევიუ მუშაობს ერთდროულად. AI-Agent-IP ($15/თვე, 4 vCPU, 4 GB RAM, 40 GB დისკი) თავისუფლად იტევს რამდენიმე პატარა ვებაპლიკაციას, თითოეული 512 MB ლიმიტით. ყველაზე მძიმე Docker-ის აწყობებია, ამიტომ დიდი იმიჯების შემთხვევაში დისკსა და მეხსიერებას თვალი ადევნეთ.

wildcard სერტიფიკატი მჭირდება?

არა. Caddy ყოველი პრევიუს ქვედომენისთვის თავად იღებს ცალკე სერტიფიკატს. wildcard მხოლოდ DNS ჩანაწერია. Let's Encrypt რეგისტრირებულ დომენზე კვირაში დაახლოებით 50 ახალ სერტიფიკატს უშვებს, რაც სავსებით საკმარისია, თუ აგენტი ასობით ტოტს არ ქმნის.

შეუძლია აგენტს თავისი SSH გასაღებით სერვერის გაფუჭება?

ამ გასაღებით — არა. ის ერთ ბრძანებაზეა შეზღუდული, რომელიც მხოლოდ „up <ტოტი>“-ს ან „down <ტოტი>“-ს იღებს უსაფრთხო სახელით. shell წვდომა, დამატებითი არგუმენტები და პორტების გადამისამართება უარყოფილია.

იმუშავებს NAT ტარიფზე?

არა. პრევიუები საკუთარ ქვედომენებზე 80 და 443 პორტებზე უნდა იყოს ხელმისაწვდომი, ამისთვის კი საჯარო IPv4 არის საჭირო. NAT ტარიფები მხოლოდ SSH პორტს ამისამართებს.

კომენტარები

ჯერ არ არის კომენტარები. იყავით პირველი.

დატოვეთ კომენტარი

კომენტარები მოდერირდება გამოჩენამდე.