full-cycle-website
Skill1 starsChanged 28 days agoMITView on GitHub
Use when you need to build and launch a complete, turnkey website autonomously: code, SEO, API documentation, git versioning, Docker, CI/CD, manual installation on a VPS/VDS/dedicated server (including servers that already run NGINX/Caddy and other sites), deploy key, a curl-based update script, SSL, and domain setup.
- Pipes a download into a shell
- Reads credentials
In this repository3 other files it gives its agents.
- design-forgeSkill
- design-systemSkill
- minecraft-builderSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 9 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Ask the user only for what you cannot infer:
- Very specific: line 25
If DESIGN.md exists: read it before building any UI and follow it strictly (colors, typography, grid, spacing, components, tone).
- Very specific: line 26
If there is no DESIGN.md: ask whether one is coming.
- Distinctive: line 54
If the site has an API (its own backend, form endpoints, webhooks), documentation is mandatory and lives in the repository:
- Very specific: line 59
When the API changes, update the spec, docs/API.md and CHANGELOG.md in the same PR.
- Distinctive: line 70
Before writing the guide, if you have SSH access, build a picture of the server using read-only commands only.
- Very specific: line 80
B. NGINX already on the host: Do not install a second proxy.
- Very specific: line 81
C. Caddy already on the host: Add a separate site file (/etc/caddy/sites/<domain>.caddy) included via import.
- Distinctive: line 85
Never bind 80/443 from the project's containers.
- Very specific: line 87
Before adding a domain, make sure that server_name/address is not already served by another config.
- Distinctive: line 89
Do not change global server settings (SSH, firewall, Docker daemon) if the server is already set up and serving other sites.
- Distinctive: line 94
start with the audit (section 7) and branch explicitly by scenario.
- Very specific: line 98
Commit proxy configs to the repository as templates: deploy/nginx/site.conf.template, deploy/caddy/site.caddy.template, …
- Very specific: line 103
Add a host alias to ~/.ssh/config (Host github-<repo>, HostName github.com, IdentityFile ~/.ssh/<repo>_deploy, IdentitiesOnly yes) so …
- Very specific: line 105
Verify: ssh -T git@github-<repo> and git ls-remote git@github-<repo>:<owner>/<repo>.git.
- Very specific: line 113
if email is hosted on the domain: MX, SPF, DKIM, DMARC.
- Very specific: line 114
Verify propagation with dig/nslookup and only then issue the SSL certificate.
- Distinctive: line 128
If the check fails: automatically roll back to the previous commit and images, re-check, exit non-zero with a clear message.
- Very specific: line 129
If the update changed the proxy template: don't apply it silently.
- Distinctive: line 130
Never touch other Compose projects, containers, networks, volumes or proxy configs.
- Distinctive: line 168
Never ask for passwords or keys in chat.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Turnkey website: from idea to production
Goal: a working site on its domain over HTTPS, running in Docker, with an SEO baseline, API documentation, git history, manual installation guide, and an update script that runs with a single curl command. The site must coexist peacefully with existing sites and proxies on the server. It is done only when the acceptance checklist at the end passes.
0. Brief (ask once, decide the rest yourself)
Ask the user only for what you cannot infer:
- the site's purpose, pages, languages, target audience and region;
- the domain (the user registers it themselves, e.g. at reg.ru or Namecheap) and whether
wwwis needed; - the server: IP, SSH user, OS; whether it is fresh or already hosts other sites. Never ask for secrets in chat; only via secure input (environment variables);
- the repository (GitHub/GitLab/other), public or private, and where to send notifications;
- whether forms, a CMS, analytics (Google Analytics / Yandex Metrica), a backend, an API or a database are needed.
Choose everything else (stack, structure, configs) yourself and record it briefly in
docs/DECISIONS.md.
1. Design: DESIGN.md
- The design system is produced by the user's separate skills and lives in
DESIGN.mdat the repository root (or wherever the user specifies). - If
DESIGN.mdexists: read it before building any UI and follow it strictly (colors, typography, grid, spacing, components, tone). Do not rewrite or extend it on your own initiative; list any gaps and contradictions you find for the user. - If there is no
DESIGN.md: ask whether one is coming; if the user says not to wait, build a neutral, clean design and note this in the report. - Move design tokens from
DESIGN.mdinto CSS variables / theme config instead of hardcoding them.
2. Stack and Docker (mandatory)
- Content site / landing page: a static site generator (Astro, Next.js static export, Hugo) served by a lightweight container (nginx:alpine / caddy:alpine inside the app container).
- Dynamic: Next.js/Nuxt/Django/Laravel/FastAPI, etc.
- The whole application (site, backend, DB, workers) runs in Docker via
docker-compose.yml(plusdocker-compose.prod.ymlif needed). Multi-stageDockerfile, non-root user in the container,HEALTHCHECK,restart: unless-stopped, log limits (max-size). - Isolation from other sites on the server:
- a unique Compose project name (
name: <project>/COMPOSE_PROJECT_NAME); all containers, networks and volumes prefixed with the project name; - the DB and internal services publish no ports externally, only on the project's internal network;
- the web container is published only on
127.0.0.1:<APP_PORT>, never on0.0.0.0and never on 80/443;APP_PORTis set in.env.
- a unique Compose project name (
- Tag images with the version (
<project>:v1.2.3and:sha-<commit>) so rollback is possible.
3. Repository and versioning
git init,.gitignore,.dockerignore,.editorconfig,README.md(how to run locally, link to the install guide, the update command),.env.examplewith no real secrets.- Branches:
main= production; work happens in feature branches, merged via PR. - Conventional Commits, semantic versioning (
v1.0.0),CHANGELOG.md; tag releases. - Linter, formatter, pre-commit hooks; tests covering at least the build, key pages and API endpoints.
4. Development
- Responsive layout per
DESIGN.md, accessibility (alt text, contrast, semantic tags, heading order). - Performance: optimized images (WebP/AVIF,
srcset, lazy-load), minimal JS, static asset caching, fonts withfont-display: swap. - 404/500 pages, favicon and
site.webmanifest. - Forms: validation, spam protection (honeypot/captcha), delivery to email/Telegram configured via environment variables.
- A
/health(or/api/health) endpoint for update checks and monitoring. - Legal: a privacy policy and cookie consent if analytics are used (comply with applicable privacy laws such as GDPR or Russia's 152-FZ).
5. API documentation
If the site has an API (its own backend, form endpoints, webhooks), documentation is mandatory and lives in the repository:
- An OpenAPI 3 spec in
docs/api/openapi.yaml, generated from code where the framework supports it (FastAPI, NestJS, drf-spectacular, etc.), otherwise hand-written and checked with a validator. docs/API.md: base URL, authentication, error formats, rate limits, API versioning (/api/v1), and for every endpoint: method, path, parameters, request body, responses with status codes, andcurlexamples.- Interactive docs (Swagger UI / Redoc / Scalar) at
/api/docs; in production, protect them with basic auth or an IP allowlist if the API is not public. - CI checks that the spec is valid and matches the code.
- When the API changes, update the spec,
docs/API.mdandCHANGELOG.mdin the same PR.
6. SEO
robots.txt(with a link to the sitemap; disallow/api/, admin and internal paths; on staging, block indexing entirely).sitemap.xmlgenerated automatically at build time.- A unique
<title>andmeta descriptionon every page,canonical,hreflangfor multilingual sites,langon<html>. - Open Graph and Twitter Card, JSON-LD structured data (Organization, WebSite, BreadcrumbList, Product/Article as appropriate).
- Human-readable URLs, one canonical host (301 from www/non-www and from http to https), no redirect chains.
- Prepare instructions for the user: verify the site in Google Search Console and Yandex Webmaster, and submit the sitemap.
7. Server audit before installation (read-only)
Before writing the guide, if you have SSH access, build a picture of the server using read-only commands only; if you don't, make these commands the first step of the guide so the user can send you the output:
- OS and resources:
cat /etc/os-release,free -h,df -h. - Ports in use and who holds them:
ss -ltnp. - Host proxies:
systemctl is-active nginx caddy apache2 haproxy traefik,nginx -T(list ofserver_names),caddy list-modules/ contents of/etc/caddy/Caddyfileand its included files. - Proxies in Docker:
docker ps --format '{{.Names}} {{.Image}} {{.Ports}}'(nginx-proxy, Traefik, Caddy, NPM on 80/443). - Existing Compose projects, networks and volumes:
docker compose ls,docker network ls,docker volume ls. - Certificates already issued and what renews them (certbot timers, Caddy storage).
- Firewall:
ufw status/nft list ruleset. Based on the findings, pick one scenario: - A. Clean server. Nothing on 80/443: install Caddy (default) or NGINX as a shared reverse proxy for all future sites, so later sites plug into the same one.
- B. NGINX already on the host. Do not install a second proxy. Add only your own file
/etc/nginx/sites-available/<domain>.conf(orconf.d/<domain>.conf) withproxy_pass http://127.0.0.1:<APP_PORT>, symlink it intosites-enabled, and issue the certificate withcertbot --nginx -d <domain>(or webroot), which touches only your own server block. - C. Caddy already on the host. Add a separate site file (
/etc/caddy/sites/<domain>.caddy) included viaimport; if there is noimportyet, add a singleimport sites/*line to the main Caddyfile, keeping a backup. - D. The proxy runs in Docker (Traefik, nginx-proxy, Caddy-docker-proxy, NPM). Attach the container to its network and describe the site with labels/variables (
VIRTUAL_HOST, Traefik labels) instead of publishing a port; do not touch the proxy's own configuration. - E. Unknown or non-standard proxy, or a conflict that cannot be resolved safely. Stop and describe the situation and the options to the user. General conflict rules:
- Never bind 80/443 from the project's containers; never stop, restart or rewrite other sites, containers, certificates or configs.
- Pick a free
APP_PORT(ss -ltn+ checkdocker ps) from a range such as 8100–8999, and record it in.envanddocs/DECISIONS.md. - Before adding a domain, make sure that
server_name/address is not already served by another config. - Any proxy change: back up the file first, then validate (
nginx -t/caddy validate --config ...), thenreloadonly, neverrestart; if validation fails, roll back your file and do not reload. - Do not change global server settings (SSH, firewall, Docker daemon) if the server is already set up and serving other sites; give hardening recommendations in a separate, optional section.
8. Manual installation: docs/INSTALL.md
The user performs installation manually, following a step-by-step guide the agent writes for the chosen scenario (A–E). Do not create a curl | bash installer. The guide must:
- give, for each step, exact copy-pasteable commands, a one-line explanation, and a command to verify the result;
- start with the audit (section 7) and branch explicitly by scenario;
- cover: installing Docker and Compose if missing (official Docker repository); creating a deploy user and the
/opt/<project>(or/srv/<project>) directory; setting up the deploy key (section 9); cloning; filling in.envfrom.env.examplewith a freeAPP_PORT; the firstdocker compose up -d --buildand the checkcurl -fsS http://127.0.0.1:<APP_PORT>/health; hooking into the proxy per scenario; DNS (section 10) and issuing SSL; setting up backups; verifying the site over HTTPS; - for a clean server (scenario A), add baseline hardening: a sudo user, key-only login, ufw (22, 80, 443), fail2ban, automatic security updates, swap on low-memory machines;
- end with a "Troubleshooting" section covering common failures (port in use,
nginx -tfails, certificate not issued due to DNS, unhealthy container) and how to roll back your changes without affecting other sites. Commit proxy configs to the repository as templates:deploy/nginx/site.conf.template,deploy/caddy/site.caddy.template,deploy/traefik/labels.example.
9. Server access to the repository: deploy key (mandatory)
The server pulls code only via a dedicated deploy key bound to a single repository, never via the user's personal keys or tokens.
- On the server, as the deploy user:
ssh-keygen -t ed25519 -C "deploy@<domain>" -f ~/.ssh/<repo>_deploy -N "". - Add a host alias to
~/.ssh/config(Host github-<repo>,HostName github.com,IdentityFile ~/.ssh/<repo>_deploy,IdentitiesOnly yes) so several sites with their own keys can live on one server; add the host fingerprint toknown_hostsviassh-keyscan. - Add the public key to the repository as a read-only deploy key (GitHub: Settings, Deploy keys, Allow write access off; GitLab: Settings, Repository, Deploy keys). If the agent has admin API access to the repository, add the key via the API (GitHub:
POST /repos/{owner}/{repo}/keyswithread_only: true) after the user agrees; otherwise state in the guide exactly where to paste the key. - Verify:
ssh -T git@github-<repo>andgit ls-remote git@github-<repo>:<owner>/<repo>.git. - The private key never leaves the server and never ends up in git, chat or CI logs.
- To trigger updates from CI, use a separate key (stored in CI secrets, public part in the deploy user's
authorized_keys, ideally restricted withcommand=to the update script); don't confuse it with the deploy key.
10. Domain and DNS
The user registers the domain. Give them exact instructions for their registrar:
- an
Arecord for@pointing to the server IP (plusAAAAif there is IPv6); AorCNAMEforwww;- if email is hosted on the domain: MX, SPF, DKIM, DMARC.
Verify propagation with
dig/nslookupand only then issue the SSL certificate.
11. Update script via curl: deploy/update.sh
The only automated script for the server: it updates an already installed site. Run it on the server as the deploy user:
curl -fsSL https://raw.githubusercontent.com/<owner>/<repo>/main/deploy/update.sh | bash -s -- --dir /opt/<project> --ref v1.2.3For a private repository, the raw URL isn't reachable without auth; in that case the README command uses the local copy from the clone (bash /opt/<project>/deploy/update.sh --ref v1.2.3) or downloads a release asset; pick one and document it in the README and docs/INSTALL.md.
Requirements:
#!/usr/bin/env bash,set -euo pipefail, clear messages for every step, a log in the project directory (/opt/<project>/logs/update.log).- Options:
--dir(install directory),--ref(branch, tag or commit; defaults to the latest tag ormain),--dry-run,--rollback,--yes. - Preflight checks: the directory exists and is a git clone of the right repository,
.envis present, Docker is available, there is enough free disk space; otherwise stop without changing anything and point todocs/INSTALL.mdfor installation. - Locking with
flockso two updates never run at once. - Steps: record the current commit and image tags;
git fetchvia the deploy key andcheckoutthe requested--ref; diff.env.exampleagainst.envand warn about new variables (never overwrite.env); back up the DB before migrations;docker compose pull/build;docker compose up -dfor your own project only (-p <project>); migrations; wait for/healthon127.0.0.1:<APP_PORT>with a timeout. - If the check fails: automatically roll back to the previous commit and images, re-check, exit non-zero with a clear message.
- If the update changed the proxy template: don't apply it silently; print the diff and the command to apply it manually (with
nginx -t/caddy validateandreload), because the proxy is shared. - Never touch other Compose projects, containers, networks, volumes or proxy configs; prune only your own project's old images, keeping the last N for rollback.
- At the end: version before and after,
/healthstatus, site URL, how to roll back (--rollback). - The script passes
shellcheck; testing it in a test environment (a container or VM with the same OS) is mandatory.
12. CI/CD
- CI on every PR: install dependencies, lint, test, build the Docker image, validate the API spec,
shellcheckfordeploy/*.sh. - Release: a
vX.Y.Ztag builds and pushes the image to a registry (if used) and creates a GitHub Release with the CHANGELOG. - CD (if the user wants it): after a release, CI calls
deploy/update.sh --ref <tag> --yeson the server over SSH and fails if the script returns an error. Do not enable auto-deploy without the user's consent; otherwise updates are run manually with thecurlcommand. - Optional: a staging environment on a subdomain with indexing blocked.
- Secrets live only in CI secrets and the server's
.env, never in git.
13. Operations
- Backups: DB and uploaded files on a schedule (cron/systemd timer of the deploy user), stored off-server, with restore tested.
- Uptime monitoring (an uptime check on
/health), Docker log limits, SSL expiry alerts. - Analytics (Google Analytics / Yandex Metrica) with the user's consent.
14. Acceptance checklist (verify it yourself, don't just claim it)
- The UI matches
DESIGN.md(if present); deviations are listed. - Everything runs in Docker; the web container listens only on
127.0.0.1:<APP_PORT>; the project does not occupy ports 80/443. - Other sites and containers on the server work as they did before installation; the proxy config passes
nginx -t/caddy validate. - The site opens at
https://domainandhttps://www.domainwith a single canonical variant; http redirects to https. - Valid SSL, auto-renewal configured.
robots.txtandsitemap.xmlare reachable and correct; meta, OG and JSON-LD are in place.- Lighthouse: Performance, SEO, Accessibility and Best Practices at 90 or above (or an explanation why not).
- 404 works; no broken links.
- API docs:
openapi.yamlis valid,docs/API.mdis current,/api/docsopens, thecurlexamples work. - The server pulls code via a read-only deploy key; no personal keys or tokens on the server.
docs/INSTALL.mdhas been walked through step by step in a test environment for the relevant scenario.- The
curl ... update.shcommand updates the site and automatically rolls back a broken release. - A backup is created and restores successfully.
- The repository contains a README (with the update command),
docs/INSTALL.md, DECISIONS, CHANGELOG,docs/API.md,deploy/; no secrets in git.
15. Report to the user
Briefly: links to the site, the repository and the API docs; the chosen server scenario and APP_PORT; a link to docs/INSTALL.md; the full curl update command; what the user still has to do by hand (installation steps, DNS at the registrar, the deploy key if the agent couldn't add it, verification in Google Search Console / Yandex Webmaster).
Rules
- Get the user's approval for actions that change production or third-party accounts (DNS, deploy key via API, shared proxy config, data deletion, payments).
- On a shared server, change only what belongs to the project; anything shared (proxy, firewall, SSH) only with a backup, validation and consent.
- Never ask for passwords or keys in chat.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

