慣性聚合 関心のあるブログ、ニュース、テクノロジーを効率的に追跡
原文を読む 慣性聚合で開く

おすすめ購読元

WordPress大学
WordPress大学
G
Google Developers Blog
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
I
InfoQ
Last Week in AI
Last Week in AI
博客园 - 司徒正美
T
Tailwind CSS Blog
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
小众软件
小众软件
李成银的技术随笔
T
The Blog of Author Tim Ferriss
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
月光博客
月光博客

DEV Community

🧠 Hermes Agent Assistant — A Modular AI Agent System with Planner, Executor & Memory Spring Boot Auto-Configuration Source Code: Nail This Interview Question The Ultimate Guide to Free AI API Keys: 6 Platforms You Need to Know Why 91% of AI Agents Fail in Production (And What the 9% Do Differently) TryHackMe | Battery | WALKTHROUGH Stop Guessing Your Regex — Test It Live in the Browser I Built FreelancEye, an Open-Source Mobile PWA for Finding Clients Beyond the Hype: My Production Playbook for Docker Swarm Top AI App Builder Platforms with Integrated Backend, Hosting & Database ECS vs EKS in 2026: An Honest Comparison from Someone Who Has Run Both in Production Hardening Your Node.js App Against Supply Chain & Remote Code Execution Attacks linux commands A Practical GEO Case: How an AI System Started Recommending Our Blog Your AI Agent Works 24/7 and Earns $0. I Built the Fix. Your AI Trading Agent Will Lose All Your Money — Here's How To Stop It Google I/O 2026: What Happens When Everything Connects? Why AI writes software but doesn’t build a good product Beyond the Hype: How Google I/O 2026 Secretly Democratized Production-Ready AI Agents with Managed Sandboxes. The Killer Assumption Test: How to Spot Doomed Product Decisions Before You Ship Stop Describing Your Bugs — Just Screenshot Them # I Built an AI Website Builder and Here's What Actually Happened Cooking an AI Campaign in 5 Minutes with Google Cloud AI APIs Your PM Retrospectives Are Lying to You How I Built a Free, Self-Hosted Pipeline That Auto-Generates Faceless YouTube Shorts TypeScript 54 to 58: The Features That Actually Matter in 2026 How to Tailor Your CV to Any Job Posting in 2026 The 7-day SaaS MVP loop: ship fast, then validate with people who actually show up 95. Fine-Tuning LLMs: Make a General Model Do Your Specific Job What Is a Frontend Developer Roadmap and Why You Need One Google shipped three Gemini "Flash" models. Picking the wrong one could 6 your AI bill Building an MCP server so Claude can query my SaaS analytics directly Google I/O 2026 and the Rise of the AI Ecosystem Your Docker Builds Are Slow Because You're Doing It Wrong (And I Built a Tool to Prove It) How do you verify GitHub contributions without trusting self-reported skills? CV vs Resume: What's the Difference and Which Do You Need? student Devs: Build AI Agents & Compete for $55K in Prizes 🚀 How to Write a Cover Letter That Actually Gets You Interviews Battle-Tested: What Getting Hacked Taught Me About Web & Cyber Security Unda folders za kuandika code >> mkdir src >> cd src >> mkdir controllers database routes services utils >> cd .. Directory: C:\Users\mwaki\microfinance-system Mode LastWriteTime Length Name Code Coverage .NET AI slop debt" is technical debt on fast forward. Nobody's ready. Multi-Head Latent Attention (MLA) Memoria - A Local AI Reading Companion Powered by Gemma 4 Stop Trusting Your Accuracy Score: A Practical Guide to Evaluating Logistic Regression Models Serious Question: Is the Developer Job Actually in Risk Due to AI? published: true tags: #discuss #career #ai #help rav2d: We ported an AV2 video decoder from C to Rust — here's why Your New Domain's First Week of GA4 Is a Lie: 4 Days of Raw Data from a Launch Gemma Guide - Real-Time Spatial Awareness for Blind Users From YAML to AI Agents: Building Smarter DevOps Pipelines with MCP A Field Guide to Human–AI Relations (For the Newly Bewildered Mortal)
AWS Secrets Managerにカマルの秘密を保存し、安価なHetzner VPSにデプロイする
Derrick Amen · 2026-05-23 · via DEV Community

Derrick Amenuve

カマルとの問題に直面しました。私の.kamal/secretsファイルには、ラップトップ上に平文でAPIキーが大量に保存されていました。アクセスできる誰でもそれらを読み取ることができました。

TLDR; カマルを使用し、AWS Secrets Managerと、Hetzner VPSにデプロイしてください。平文の秘密はありません、安価なホスティング、コンプライアンスに満足です。

問題

カマルはアプリのデプロイに最適です。しかし、デフォルトではシークレットは平文ファイルに保存されています。SOC 2やGDPRの要件にはこれでは不適切です。管理されたストアが必要です。私はAWS Secrets Managerを選びました

しかし、それから別の問題に直面しました。kamal secrets fetch --adapter aws_secrets_managerコマンドは--fromそれぞれのキーが独自のAWSシークレットであることを期待します。すべてをJSONの塊として保存すると(私がしたように)、以下のようになります:

ERROR (RuntimeError): myapp/production/secrets//DEEPGRAM_API_KEY: Secrets Manager can't find the specified secret.

フルスクリーンモードに入る フルスクリーンモードから退出する

ステップ1: Hetzner VPS

Hetzner CAXシリーズは月約4ユーロからスタートします。私はCX22を使用しており、2つのvCPUと4GBのRAMを搭載しています。生産用には十分です.

# On your Hetzner server
apt update && apt install -y docker.io

# Copy your SSH key so Kamal can connect
ssh-copy-id root@your-server-ip

フルスクリーンモードに入る フルスクリーンモードから退出する

あなたのconfig/deploy.yml:

servers:
  web:
    hosts:
      - runtime.yourdomain.com

proxy:
  ssl: true
  hosts:
    - runtime.yourdomain.com
  healthcheck:
    path: /health/ready

registry:
  server: docker.io
  username: your-docker-user
  password:
    - KAMAL_REGISTRY_PASSWORD

フルスクリーンモードに入る フルスクリーンモードを終了

Docker Hubのアカウントと個人アクセストークンが必要ですKAMAL_REGISTRY_PASSWORD.

ステップ2: AWSでシークレットを作成

AWS Secrets Managerコンソールで:

  1. シークレットマネージャーに移動>新しいシークレットを保存
  2. 「他の種類の秘密」を選択
  3. プレートテキストタブに切り替え、JSONを貼り付ける
{
  "DEEPGRAM_API_KEY": "your_deepgram_key",
  "ASSEMBLY_AI_API_KEY": "your_assemblyai_key",
  "REDIS_URL": "redis://:password@your-redis:6379",
  "KAMAL_REGISTRY_PASSWORD": "your_docker_token"
}

全画面表示モードに入る 全画面表示モードから抜ける

  1. 名前をつけるmyapp/production/secrets
  2. 保存する

サーバーに近い地域を選択。Hetznerのボックスがドイツにある場合はeu-central-1(フランクフルト)を使用する。遅延を低くし、GDPRを満たす。

ステップ3: テーブルトップ用のIAMユーザー

テーブルトップはデプロイ中にシークレットを読むための許可が必要です。

  1. IAMに移動して、 > ユーザー > > ユーザーを作成
  2. ユーザー名を kamal-deploy
  3. コンソールアクセスをオフにする(CLIのみ)
  4. グループを作成してsecrets-manager SecretsManagerReadWriteポリシーを持つ
  5. バッチ読み取り用のインラインポリシーを追加:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret",
        "secretsmanager:BatchGetSecretValue",
        "secretsmanager:ListSecrets"
      ],
      "Resource": "*"
    }
  ]
}

フルスクリーンモードに入る フルスクリーンモードから退出する

  1. あなたのユーザーをグループに追加

IAMポリシーは数分かかることがあります。最初に失敗した場合は30秒待って再度試す

ステップ4: AWS CLIを設定

aws configure
# AWS Access Key ID: paste from IAM user
# AWS Secret Access Key: paste
# Default region name: eu-central-1
# Default output format: json

フルスクリーンモードに入る フルスクリーンモードを終了

テストを実行

aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text | head -c 50

フルスクリーンモードを開始 フルスクリーンモードを終了

あなたのJSONの始まりが見えるはずです

ステップ5:.kamal/secretsファイルをフォーマットする

ここでつまずきました。--fromフラグは、各キーごとに1つのAWSシークレットを要求します。20個の別々のシークレットがあるのは面倒です。確認してくださいカマルの秘密文書について詳しくはこちらをご覧ください.

代わりに、私はPythonを使用してAWS CLIで抽出します。各行は独立しています:

# AWS Secrets Manager: myapp/production/secrets (eu-central-1)
DEEPGRAM_API_KEY=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['DEEPGRAM_API_KEY'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")
ASSEMBLY_AI_API_KEY=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['ASSEMBLY_AI_API_KEY'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")
REDIS_URL=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['REDIS_URL'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")
KAMAL_REGISTRY_PASSWORD=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['KAMAL_REGISTRY_PASSWORD'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")

フルスクリーンモードに入る フルスクリーンモードから退出する

各行は完全なJSONを取得し、1つのキーを抽出します。カマルは各行を独自のサブシェルで評価するため、各行間で共有変数はありません。これが機能します。

お好みでjqを使用することもできます:

DEEPGRAM_API_KEY=$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text | jq -r '.DEEPGRAM_API_KEY')

フルスクリーンモードを開始 フルスクリーンモードを終了

ステップ6:デプロイ

kamal deploy

フルスクリーンモードを開始 フルスクリーンモードを終了

カマルはデプロイ時にAWSからシークレットを取得し、それをあなたのコンテナに注入します。平文ファイルは決してサーバーに触れることはありません。

製造とステージング

各環境ごとに異なるAWSシークレットを使用しています。両方ともAWSからプルし、平文はどこにも存在しません.

# .kamal/secrets  (used by kamal deploy)
DEEPGRAM_API_KEY=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['DEEPGRAM_API_KEY'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")
KAMAL_REGISTRY_PASSWORD=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['KAMAL_REGISTRY_PASSWORD'])" "$(aws secretsmanager get-secret-value --secret-id myapp/production/secrets --query SecretString --output text)")

# .kamal/secrets.staging  (used by kamal deploy -d staging)
DEEPGRAM_API_KEY=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['DEEPGRAM_API_KEY'])" "$(aws secretsmanager get-secret-value --secret-id myapp/staging/secrets --query SecretString --output text)")
KAMAL_REGISTRY_PASSWORD=$(python3 -c "import json,sys; print(json.loads(sys.argv[1])['KAMAL_REGISTRY_PASSWORD'])" "$(aws secretsmanager get-secret-value --secret-id myapp/staging/secrets --query SecretString --output text)")

フルスクリーンモードを入力 フルスクリーンモードを退出

ファイル間ではシークレット名のみが変更されます。myapp/production/secrets プロダクション用、myapp/staging/secrets ステージング用。kamal deploy -d staging を実行し、Kamalはステージングファイルから読み取ります。

両方の秘密はAWSにあります。プレーンテキストのステージング資格情報もありません。これはSOC 2にとって重要ですなぜなら監査人はすべての環境を確認するからです

やりました

プレーンテキストの秘密はもうありません。SOC 2とGDPRの要件を満たしました。Hetznerの請求額は月5ユーロを下回ります

大きく感謝しますAWSドキュメントチームKamalメンテナーHetznerがホスティングを手頃な価格で提供してくれてありがとう。これであなたも私が直面したような頭痛を回避できるといい。それでは、再度開発に戻ろう。