Free

לתת ל-Claude לפרוס ל-production

לטעויות פריסה אין תסמינים. ארבעה מעקות — vaults נפרדים, סקריפטי EDITOR, קריאה חזרה לאימות, החלפת runtime לפי env — כדי להשתמש ב-Claude בלי לשרוף הכל.


ההבדל הגדול בין פריסה לבין כתיבת קוד: פריסה היא חד-פעמית, בסיכון גבוה, וקשה להחזיר אחורה. כתבת שורת קוד שבורה — ריצת טסטים אחת תופסת. כתבת שורת credentials שבורה — תגלה רק כשהתשלום האמיתי הראשון נכשל — המשתמשים כבר חויבו בכרטיס, הכסף לא הגיע לחשבון שלך, הלוגים מלאים ב-400.

לאחרונה העברתי את how2claude מפיתוח מקומי ל-production יחד עם Claude: חשבון Stripe live, ארנק x402 mainnet, Google OAuth, Kamal secrets. Claude לא יודע אילו ערכים הם לטסט ואילו אמיתיים. לא יודע ש-sk_live_ מול sk_test_ זה הבדל של אות אחת עם השלכות של סוף העולם. את המעקות אתה בונה.

מעקה #1: קבצי credentials נפרדים ל-dev ול-prod

ברירת המחדל של Rails היא config/credentials.yml.enc, מפוענח על ידי config/master.key. אם אתה משתמש בברירת המחדל הזו — הפסדת.

אם תכניס sk_live_xxx לקובץ הזה ואז תריץ טסטים מקומית, קוד הטסט שלך משתמש ב-Stripe production. כל ריצה מחייבת כרטיס אמיתי.

פצל לשניים:
- config/credentials.yml.enc + config/master.key: dev/test, מחזיק sk_test_xxx
- config/credentials/production.yml.enc + config/credentials/production.key: prod, מחזיק sk_live_xxx

שני קבצי ה-.key ב-.gitignore, שני ה-.enc בקומיט. production.key חי רק על מכונת ה-deploy.

אז Kamal secrets צריך להצביע על הקובץ הנכון:

 # .kamal/secrets
-RAILS_MASTER_KEY=$(cat config/master.key)
+RAILS_MASTER_KEY=$(cat config/credentials/production.key)

בתוך הקונטיינר, RAILS_MASTER_KEY מצביע עכשיו על המפתח של ה-production, ומה שמפוענח הוא credentials של production. שמתי לב כש-Claude כתב את השורה הזו — תבנית ברירת המחדל של Kamal היא config/master.key (של ה-dev), שפורסת בשקט את ה-Stripe key של ה-dev ל-production.

מעקה #2: השתמש בסקריפט EDITOR, לא בהעתק-הדבק

bin/rails credentials:edit --environment production פותח עורך אינטראקטיבי. Claude לא יכול לנהוג עורך אינטראקטיבי. גם אתה לא רוצה להדביק ידנית עשרות סודות (טעות הקלדה אחת והכל נשבר).

השתמש בתבנית הזו:

EDITOR="ruby script/set_prod_webhook_secret.rb" \
  bin/rails credentials:edit --environment production
rm script/set_prod_webhook_secret.rb

script/set_prod_webhook_secret.rb נראה ככה:

# ARGV[0] הוא הנתיב לקובץ ה-YAML הזמני שפוענח
file = ARGV[0]
require "yaml"
data = YAML.load_file(file) || {}
data["stripe"] ||= {}
data["stripe"]["webhook_secret"] = "whsec_GHWObNAKFh2HPOlJpbGmlYfIiKz1C8EY"
File.write(file, data.to_yaml)

Rails כותב את ה-YAML המפוענח לקובץ זמני, קורא ל"EDITOR" שלך עם הנתיב הזה כארגומנט, ומצפין מחדש ביציאה. ה"EDITOR" שלך הוא בעצם סקריפט Ruby שמשנה מפתח אחד בצורה כירורגית ושומר.

למה זה טוב:
- מדויק: נוגע רק ב-stripe.webhook_secret, לא בכלום אחר.
- אידמפוטנטי: להריץ פעמיים כמו להריץ פעם.
- ניתן לביקורת: הסקריפט הוא ה-diff. Claude כותב, אתה מעיף מבט, אתה יודע בדיוק מה ישתנה.
- נעלם במחיקה: אחרי rm אין credential בטקסט רגיל על הדיסק, אין הדבקה של whsec_... בהיסטוריית ה-shell.

סקריפט לכל credential: set_stripe_live_key.rb, set_webhook_secret.rb, set_price_ids.rb, set_wallet_address.rb. rm לכל אחד מיד אחרי.

מעקה #3: אמת על ידי קריאה חזרה עם Rails runner

אחרי שכתבת, אל תסמוך על זה שהוא כתב נכון. קרא חזרה:

bin/rails runner -e production "
c = Rails.application.credentials
puts 'sk_live set: ' + c.dig(:stripe, :secret_key).to_s.start_with?('sk_live_').to_s
puts 'webhook_secret set: ' + c.dig(:stripe, :webhook_secret).to_s.start_with?('whsec_').to_s
puts 'wallet prefix: ' + c.dig(:x402, :wallet_address).to_s[0..5]
puts 'wallet len: ' + c.dig(:x402, :wallet_address).to_s.length.to_s
"

המפתח הוא בדיקות prefix ואורך, לא רק להדפיס את הערכים.

  • secret של Stripe live תמיד מתחיל ב-sk_live_. אם אתה קורא חזרה sk_test_, Claude שם את ה-test key בקובץ prod — באג שלא תמצא עד התשלום האמיתי הראשון.
  • webhook secrets תמיד מתחילים ב-whsec_. פורמט נכון או לא, נראה במבט אחד.
  • כתובות ארנק EVM תמיד 42 תווים, 0x.... אורך שגוי אומר שתו אחר התגנב פנימה.

הוספת בדיקות prefix חוסמת את רוב טעויות ההקלדה, שדות נשמטים וסביבות מעורבבות.

מעקה #4: החלף ב-runtime לפי env, לא ידנית ב-deploy

מפתה לחשוב "אני אשנה את ה-network ל-mainnet לפני ה-deploy". סוג כזה של החלפה תלוי בזיכרון אנושי. במוקדם או במאוחר זה יישרף לך.

צרב את הכלל ב-initializer:

# config/initializers/x402.rb
X402.configure do |c|
  c.wallet_address = Rails.application.credentials.dig(:x402, :wallet_address)
  c.chain = Rails.env.production? ? "base" : "base-sepolia"
end

אותו קוד, testnet (sepolia) ב-dev, mainnet (base) ב-prod. כלום לשנות ב-deploy. Claude לא יכול "לשכוח להחליף" כי ההחלפה לא העבודה שלו.

אותו טריק ל-basescan_tx_url, נראות Plan (תוכניות dev-only לא מוצגות ב-prod), בחירת Stripe price ID, וכולי. כל מה שונה בין dev ל-prod, הפוך עם Rails.env. אל תסמוך על לזכור בזמן ה-deploy.

הצעד האחרון: עבור את הזרימה האמיתית בעצמך

עם ארבעת המעקות במקום, עדיין צריך שתלחץ על תשלום כסף אמיתי בעצמך בפעם הראשונה.

במאמר הקודם לאתר באגים שקטים עם Claude תיארתי את הלחיצה הראשונה על תשלום x402 ב-production: invalid_string at payTo ב-console. התו ה-43 בכתובת הארנק היה סימן שאלה ברוחב מלא שהתגנב מ-IME סיני. בדיקות prefix לא תפסו (0x היה שם), טסטים לא תפסו (טסטים לא יורים טרנזקציות אמיתיות), רק לחיצה אמיתית הוציאה את זה החוצה.

מעקות deploy הם לא עבור Claude. הם עבורך — אוטומט את מה שאפשר לאוטמט (prefixes, אורכים, החלפות env) כדי שתשומת הלב שחסכת תלך לאינטראקציות אמיתיות שהאוטומציה לא מכסה.


הזרימה המלאה של Claude-deploy:

  1. הפרד credentials של dev ו-prod לקבצי .enc + .key נפרדים.
  2. לכל ערך שצריך להגדיר, כתוב סקריפט Ruby חד-פעמי, הזן דרך EDITOR=script, מחק מיד.
  3. אחרי כל כתיבה, קרא חזרה עם Rails runner, בדוק prefixes ואורכים.
  4. החלף את כל ההבדלים dev/prod דרך Rails.env, לא ב-deploy.
  5. על כפתור הכסף האמיתי, אתה לוחץ בפעם הראשונה.

Deploy זה לא "לכתוב קוד עם סיכונים גבוהים יותר". Deploy זה "לכתוב קוד שבו אף אחד לא אומר לך שאתה טועה". המעקות קיימים כדי להפוך "אף אחד לא אומר" ל"אתה יודע תוך 15 שניות".