diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
new file mode 100644
index 0000000..7729d54
--- /dev/null
+++ b/DEVELOPMENT.md
@@ -0,0 +1,72 @@
+# Development
+
+## Makefile targets
+
+```txt
+Usage: make [target1] [target2] ...
+
+Commands/Targets:
+help show this message
+install install project
+update update project dependencies
+format format project
+lint lint project
+build build project
+start start server in localhost
+test test project
+test-% test project with specific test
+coverage test project with coverage
+uv-sync uv sync
+uv-upgrade uv sync upgrade
+ruff ruff check
+ruff-fix ruff check (and fix)
+ruff-format ruff format
+ruff-format-check ruff format (check only)
+ty ty check
+unittest unittest
+unittest-% unittest -k [filter]
+coverage-unittest coverage run -m unittest
+coverage-report coverage report
+coverage-html coverage html
+coverage-xml coverage xml
+docker-build docker build
+docker-run docker run
+```
+
+## TODO
+
+- [x] basic http server
+- [x] docker container
+- [x] env instead of args when available
+- [x] PUT gzip data into /data/xxx
+- [x] DELETE request
+- [x] max file size
+- [x] .host in /data/xxx can be translated as host in GET /
+- [x] header to setup .host file instead of in archive
+- [x] ignore .gitignore/.host etc at root
+- [x] cerbot install in container + path env/arg
+- [x] redirect /.well-known/acme-challenge to specific path
+- [x] certbot/self-signed create/renew in specific dir
+- [x] better logger
+- [x] renew command
+- [x] https mode w/ multiple hosts
+- [x] create certificate on request
+- [x] certbot copy certificates for unique path
+- [x] better error page
+- [x] add favicon.ico + special path
+- [x] [http.server security](https://docs.python.org/3/library/http.server.html#http-server-security)
+- [x] launch separate upgrade 80->443 server when https
+- [x] token management with "generate" command and bind path to specific token
+- [x] docker compose example + .env
+- [x] 404 GET on host not found
+- [x] 403 PUT on host already taken
+- [x] remove dot files after file extract
+- [x] unit tests
+- [x] github actions
+- [x] X-Redirect
+- [x] X-Proxy
+- [ ] detect root certificate change and update server
+- [ ] detect tokens change and update token_manager
+- [ ] allow args before/after command
+- [x] proper doc
+
diff --git a/README.md b/README.md
index f205e7d..1699bcb 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,53 @@
-# Stapler
+# Stapler
+
+*Static pages as simple as a gzip file*

+## Table of Contents
+
+- [What is Stapler](#what-is-stapler)
+- [Python CLI](#python-cli)
+ - [Basic usage](#basic-usage)
+- [HTTP API](#http-api)
+ - [Create/update page from gzip](#createupdate-page-from-gzip)
+ - [Create/update page with redirect](#createupdate-page-with-redirect)
+ - [Create/update page with proxy](#createupdate-page-with-proxy)
+ - [Delete page](#delete-page)
+- [Docker](#docker)
+
+
+## What is Stapler
+
+Stapler is a **static page delivery server**.
+
+You feed it a tar.gz file of your content, and it serves it at your desired path or host.
+
+It handles:
+
+* static files delivery: `/path/xxx`
+* directory roots translation into `index.html` (if existing)
+* host translation to specific path: `my.example.com => /path/`
+* auto host discovery and certificate issuing (via certbot)
+* redirect pages: `/path-2/ => (redirect) https://my-website.com`
+* proxy pages: `/path-3/ => https://my-website.com`
+* updating/deleting content via API with `curl`
+
+## Python CLI
+
+### Basic usage
+
+Theres 3 basic commands for the stapler server:
+
+* `run`: launch the server to serve at the desired paths (see full CLI help for env vars and such)
+* `renew`: renew all existing certificates (the server must be running in the background)
+* `token`: generate a new secure API token
+
+See [Docker](#docker) for a quick deployable server.
+
+
+ Full CLI Help
+
```txt
usage: stapler [-h] [--debug | --no-debug] [-d DATA_DIR] [--certificates | --no-certificates] [--certbot | --no-certbot]
[--self-signed-path SELF_SIGNED_PATH] [--certbot-conf CERTBOT_CONF] [--certbot-www CERTBOT_WWW]
@@ -47,22 +93,34 @@ options:
(Each option can be supplied with equivalent environment variable.)
```
-## Endpoints
+
-### Create/update page
+## HTTP API
+
+### Create/update page from gzip
```txt
PUT /{page}/
+ X-Token (your API token)
+ X-Host (optional host as entrypoint)
+ (body with tar data)
```
```bash
-# create archive from 'dist' dir and upload to /my-project/
-tar -czC dist . | curl -X PUT \
- --data-binary @- \
+# create archive from 'dist' dir and upload it to /my-project/
+tar -czC dist -f dist.tar.gz .
+curl -X PUT \
-H 'X-Token: ' \
+ --data-binary "@dist.tar.gz" \
https://stapler-host/my-project/
-# create archive from 'dist' dir and upload to /my-project/ and myproject.example.com
+# same thing but one-liner
+tar -czC dist . | curl -X PUT \
+ -H 'X-Token: ' \
+ --data-binary @- \
+ https://stapler-host/my-project/
+
+# make stapler server identifiers myproject.example.com as /my-project/
tar -czC dist . | curl -X PUT \
--data-binary @- \
-H 'X-Token: ' \
@@ -70,10 +128,52 @@ tar -czC dist . | curl -X PUT \
https://stapler-host/my-project/
```
+### Create/update page with redirect
+
+```txt
+PUT /{page}/
+ X-Token (your API token)
+ X-Redirect (redirection target)
+ X-Host (optional host as entrypoint)
+```
+
+```bash
+# create /my-project/ that redirects to https://github.com/my-project
+curl -X PUT \
+ -H 'X-Token: ' \
+ -H 'X-Redirect: https://github.com/my-project' \
+ https://stapler-host/my-project/
+
+# simple redirect from root host to www
+curl -X PUT \
+ -H 'X-Token: ' \
+ -H 'X-Proxy: https://www.my-website.com' \
+ -H 'X-Host: my-website.com' \
+ https://stapler-host/my-website-www/
+```
+
+### Create/update page with proxy
+
+```txt
+PUT /{page}/
+ X-Token (your API token)
+ X-Proxy (proxy target)
+ X-Host (optional host as entrypoint)
+```
+
+```bash
+# create /my-website/ that proxies to http://localhost:8000
+curl -X PUT \
+ -H 'X-Token: ' \
+ -H 'X-Proxy: http://localhost:8000' \
+ https://stapler-host/my-project/
+```
+
### Delete page
```txt
DELETE /{page}/
+ X-Token (your API token)
```
```bash
@@ -83,71 +183,19 @@ curl -X DELETE \
https://stapler-host/my-project/
```
-## Development
+## Docker
-### TODO
+Stapler ships with a deploy-ready `Dockerfile` and a sample `docker compose` stack with:
-- [x] basic http server
-- [x] docker container
-- [x] env instead of args when available
-- [x] PUT gzip data into /data/xxx
-- [x] DELETE request
-- [x] max file size
-- [x] .host in /data/xxx can be translated as host in GET /
-- [x] header to setup .host file instead of in archive
-- [x] ignore .gitignore/.host etc at root
-- [x] cerbot install in container + path env/arg
-- [x] redirect /.well-known/acme-challenge to specific path
-- [x] certbot/self-signed create/renew in specific dir
-- [x] better logger
-- [x] renew command
-- [x] https mode w/ multiple hosts
-- [x] create certificate on request
-- [x] certbot copy certificates for unique path
-- [x] better error page
-- [x] add favicon.ico + special path
-- [x] [http.server security](https://docs.python.org/3/library/http.server.html#http-server-security)
-- [x] launch separate upgrade 80->443 server when https
-- [x] token management with "generate" command and bind path to specific token
-- [x] docker compose example + .env
-- [x] 404 GET on host not found
-- [x] 403 PUT on host already taken
-- [x] remove dot files after file extract
-- [x] unit tests
-- [x] github actions
-- [x] X-Redirect
-- [x] X-Proxy
-- [ ] proper doc
+* a main server exposing on port 80 (http) and port 443 (https)
+* a weekly crontab for updating certificates
-### Makefile targets
-
-```txt
-Usage: make [target1] [target2] ...
-
-Commands/Targets:
-help show this message
-install install project
-update update project dependencies
-format format project
-lint lint project
-build build project
-start start server in localhost
-test test project
-test-% test project with specific test
-coverage test project with coverage
-uv-sync uv sync
-uv-upgrade uv sync upgrade
-ruff ruff check
-ruff-fix ruff check (and fix)
-ruff-format ruff format
-ruff-format-check ruff format (check only)
-ty ty check
-unittest unittest
-unittest-% unittest -k [filter]
-coverage-unittest coverage run -m unittest
-coverage-report coverage report
-coverage-html coverage html
-coverage-xml coverage xml
-docker-build docker build
-docker-run docker run
-```
+```bash
+cp crontab.example crontab
+cp compose.example.yml compose.yml
+cp .env.example .env
+$EDITOR .env # update HOST and TOKEN_SALT
+docker compose up
+# whenever you need a new token
+docker compose run stapler token
+```
\ No newline at end of file