Deploy aws
A portable Claude Code skills library (plugin) for a Django 5.2 + Next.js 16 house stack: 30 model-agnostic, tenant-isolation-and-security-first skills.
npx -y skills add Deadlymind/nanolama --skill deploy-awsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 21 days oldThe repository was created 21 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Deploy runbook for this stack's Django/DRF backend on AWS Elastic Beanstalk (Gunicorn for WSGI, Uvicorn for the Channels ASGI app via Procfile, .ebextensions, leader_only migrate) and the Next.js frontend on Amplify (amplify.yml, pinned pnpm, env vars). Use when shipping a release, writing a Procfile or amplify.yml, running eb deploy, wiring container_commands, rolling back to a prior version label, or checking GET /health after a deploy. Not for provisioning RDS/ElastiCache/S3 (see aws-services) or the GitHub Actions pipeline (see ci-cd).
SKILL.md
6.0 KB, as published. Nobody here has run it
Deploy to AWS (Elastic Beanstalk + Amplify)
When to use
Shipping a backend release to Elastic Beanstalk or a frontend release to Amplify,
or debugging a deploy — Procfile process wiring, migrations on deploy, env vars,
rollback, and the post-deploy health check. Deploys are gated: never run
eb deploy or trigger a prod build without asking the user first.
Pattern
The EB instance runs two processes from one Procfile: Gunicorn serves the
WSGI app, Uvicorn serves the Channels ASGI app (websockets). Schema changes
run once per deploy via a leader_only container command, never at import
time. Secrets live in the EB/Amplify environment, never in git. After every
deploy, prove it with GET /health and roll back by redeploying the previous
version label if it is red.
Steps / idioms
The one thing to get right is the Procfile (repo root): two processes, one WSGI (Gunicorn) and one ASGI (Uvicorn pointed at the Channels application). Daphne is the local dev server — don't ship it here:
# --max-requests recycles each worker after N requests to cap memory growth;
# --max-requests-jitter staggers the recycles so they don't all restart at once
# (values illustrative — tune to your traffic and memory budget).
web: gunicorn myproject.wsgi:application --bind :8000 --workers 3 --max-requests 2000 --max-requests-jitter 200 --timeout 60 --graceful-timeout 30
asgi: uvicorn myproject.asgi:application --host 0.0.0.0 --port 5000 --workers 2
Everything else is standard EB/Amplify wiring in prose:
- Migrate once, on the leader only — in
.ebextensions/01_migrate.config, acontainer_commandsentry runningsource /var/app/venv/*/bin/activate && python manage.py migrate --noinputwithleader_only: trueso a multi-instance fleet doesn't race on locks. Add a second command forcollectstatic --noinput(noleader_onlyneeded). - Env vars via the EB environment, never committed —
eb setenv DJANGO_SETTINGS_MODULE=myproject.settings.prod SECRET_KEY=... DATABASE_URL=... REDIS_URL=..., theneb deploy. - Amplify frontend —
amplify.ymlwith a pinned pnpm inpreBuild(corepack enable, thencorepack prepare [email protected] --activate, thenpnpm install --frozen-lockfile) andpnpm run build. Neverpnpm@latest. Build-timeNEXT_PUBLIC_*vars come from the Amplify console environment. - Verify, then decide — hit the health endpoint and read the body, don't
assume:
curl -sS -w '%{http_code}\n' https://<your-api-domain>/health. - Rollback = redeploy the last-known-good version label with no rebuild:
eb appversion --listto find the prior good label, theneb deploy --version app-20260715-1.
Adapt to your repo
Rename myproject (wsgi/asgi module paths), the settings module, and the health
URL. Match the pnpm version to your packageManager field in package.json.
Confirm .ebextensions uses your actual venv activation path and that
ALLOWED_HOSTS/CSRF_TRUSTED_ORIGINS include the EB and Amplify domains. If you
run websockets, ensure the load balancer forwards the asgi port and upgrades.
Gotchas
- Ask before deploying. A deploy is a side-effecting, prod-facing action —
confirm the target env and the release with the user first. This skill carries
disable-model-invocation: true, so it is manual-only: you load it by running/nanolama:deploy-aws, and Claude cannot pull it in and decide to deploy because the code looks ready. Keep that field if you copy this runbook. - Without
leader_only: true, every instance runsmigratesimultaneously and they race on locks — one leader only (seemigrations). - Uvicorn is a production ASGI server but is not bundled with Channels; wire
the ASGI application explicitly (
uvicorn myproject.asgi:application). Daphne is the dev server; don't ship it as your prod ASGI process. pnpm@lateston Amplify makes builds non-reproducible — pin the exact version and commit the lockfile; use--frozen-lockfile.- Secrets in
.ebextensionsoramplify.ymlland in git history — keep them in the environment (eb setenv/ Amplify console) only. - Websockets connect then drop after ~60s? That's the load balancer idle
timeout, not your code. Raise the ALB idle timeout (e.g.
3600) via an.ebextensionsoption_settingsentry underaws:elbv2:loadbalancer, and confirm the LB forwards/upgrades to the ASGI port. - Make
/healthactually probe its dependencies — a cheap DB query plus a cache/broker ping, returning non-200 if either is down. A static200hides real breakage. On EB a failing health check auto-rolls-back the deploy; that's an intentional gate — don't disable it (seeverify). - Quiesce background workers before
migrate. Add aleader_only,ignore-errorscontainer command that stops the workers on the leader right before the migrate command, so they release DB connections/locks and don't race the schema change. They restart with the new release (seemigrations). - Backend-only commit still rebuilds the frontend? A push-triggered build host (Amplify) rebuilds the whole frontend on every push, even backend-only commits. Suppress non-frontend commits with a commit skip marker or a path filter so you don't burn build minutes on changes that can't affect the frontend.
- A green build is not a green deploy — the health check is the proof (see
verify).
See also
aws-servicesci-cdmigrations