Ditch_The_Agent/dta_blog is a static HTML/CSS RealPath blog (Python SSG, not a Vite SPA). Crawlers need real article HTML. Spin up beta and prod the same way we serve dta_webapp (checkout → build → nginx in web-static).
Tianji script URL is already in the built HTML (https://tianji.aimloperations.com/tracker.js). Ops does not inject ids — just serve the right --env build.
package.json also has build:prod / build:beta that mkdir + copy those webroots, so the existing node-static deploy path (npm ci then npm run build:<env>) can work. Build itself is Python 3 stdlib only — no pip, no Node compile.
Add dta_blog to app_catalog in inventory/group_vars/all.yml:
type: node-static (reuse roles/app-deploy/tasks/node_static.yml) or a thin python-static variant that runs python3 build.py --env <env> if you do not want npm ci on a no-dep package.
Put workloads on adama (and other webservers that already serve dta_webapp) in host_apps:
prod port 8086
beta port 8087
Confirm these are free vs current map (dta_webapp 8080/8081, chat 8082/8083, abc_fe 8085, …). Pick neighbors if 8086/8087 clash.
web-static nginx already does try_files $uri $uri/ /index.html — that is enough for /<slug>/ directories. Optional: add error_page 404 /404.html for this app only.
Public DNS / NPM / Cloudflare (same pattern as realpath.app → prod static port, beta.realpath.app → beta static port):
blog.realpath.app → prod 8086
beta.blog.realpath.app → beta 8087
TLS like the other RealPath names.
Document in IMPLEMENTATION.md / scripts/deploy.sh help. Gitea deploy can later mirror dta_webapp (./scripts/deploy.sh --app dta_blog --env beta|prod).
Do not reverse-proxy this onto realpath.app/blog unless product changes their mind. Logo / How it Works on the blog must keep pointing at the app origin (realpath.app vs beta.realpath.app), not at the blog host.
Acceptance criteria
dta_blog in app_catalog with beta + prod webroots under /var/www/{env}.blog.realpath.app/html.
adama (and peers) host_apps entries for prod + beta with documented ports.
./scripts/deploy.sh --app dta_blog --env beta --ref main publishes the beta build.
./scripts/deploy.sh --app dta_blog --env prod --ref main publishes the prod build.
https://blog.realpath.app/ serves prod HTML; view-source has article text, Tianji id cmtvvmf562afjzqumwt1yh2y8, and links to https://realpath.app/.
https://beta.blog.realpath.app/ serves beta HTML; Tianji id cmtvvn6z62agdzqumtk8xijpy; links to https://beta.realpath.app/; demo posts present.
https://blog.realpath.app/sitemap.xml and robots.txt / llms.txt 200.
TLS + DNS for both names. UFW only as needed for the new static ports (LAN / proxy, not world-open if NPM terminates TLS).
dta_webapp node-static + roles/web-static — copy this pattern
Tianji already configured in the SSG; no new Tianji server work
## Why
[Ditch_The_Agent/dta_blog](https://git.aimloperations.com/Ditch_The_Agent/dta_blog) is a **static HTML/CSS** RealPath blog (Python SSG, not a Vite SPA). Crawlers need real article HTML. Spin up **beta and prod** the same way we serve `dta_webapp` (checkout → build → nginx in `web-static`).
Product hosts (not `realpath.app/blog` subdirectory):
| Env | Public host | Header/footer links (baked at build) | Tianji website id |
| --- | --- | --- | --- |
| prod | `https://blog.realpath.app` | `https://realpath.app` | `cmtvvmf562afjzqumwt1yh2y8` |
| beta | `https://beta.blog.realpath.app` | `https://beta.realpath.app` | `cmtvvn6z62agdzqumtk8xijpy` |
Tianji script URL is already in the built HTML (`https://tianji.aimloperations.com/tracker.js`). Ops does not inject ids — just serve the right `--env` build.
## Build
Repo: `ssh://git@git.aimloperations.com:30009/Ditch_The_Agent/dta_blog.git` (branch `main`).
```bash
python3 build.py --env prod # dist/ → /var/www/prod.blog.realpath.app/html
python3 build.py --env beta # dist/ → /var/www/beta.blog.realpath.app/html
```
`package.json` also has `build:prod` / `build:beta` that mkdir + copy those webroots, so the existing **node-static** deploy path (`npm ci` then `npm run build:<env>`) can work. Build itself is Python 3 stdlib only — no pip, no Node compile.
Beta build **includes** `demo: true` seed posts. Prod omits them.
## Proposed server-infra work
1. Add `dta_blog` to `app_catalog` in `inventory/group_vars/all.yml`:
- `type: node-static` (reuse `roles/app-deploy/tasks/node_static.yml`) **or** a thin `python-static` variant that runs `python3 build.py --env <env>` if you do not want `npm ci` on a no-dep package.
- `repo: "{{ git_base_url }}/Ditch_The_Agent/dta_blog.git"`
- `default_branch: main`
- `webroot_pattern: "/var/www/{env}.blog.realpath.app/html"`
2. Put workloads on **adama** (and other webservers that already serve `dta_webapp`) in `host_apps`:
- prod port **8086**
- beta port **8087**
Confirm these are free vs current map (dta_webapp 8080/8081, chat 8082/8083, abc_fe 8085, …). Pick neighbors if 8086/8087 clash.
3. `web-static` nginx already does `try_files $uri $uri/ /index.html` — that is enough for `/<slug>/` directories. Optional: add `error_page 404 /404.html` for this app only.
4. Public DNS / NPM / Cloudflare (same pattern as `realpath.app` → prod static port, `beta.realpath.app` → beta static port):
- `blog.realpath.app` → prod **8086**
- `beta.blog.realpath.app` → beta **8087**
- TLS like the other RealPath names.
5. Document in `IMPLEMENTATION.md` / `scripts/deploy.sh` help. Gitea deploy can later mirror `dta_webapp` (`./scripts/deploy.sh --app dta_blog --env beta|prod`).
**Do not** reverse-proxy this onto `realpath.app/blog` unless product changes their mind. Logo / How it Works on the blog must keep pointing at the **app** origin (`realpath.app` vs `beta.realpath.app`), not at the blog host.
## Acceptance criteria
- [ ] `dta_blog` in `app_catalog` with beta + prod webroots under `/var/www/{env}.blog.realpath.app/html`.
- [ ] adama (and peers) host_apps entries for prod + beta with documented ports.
- [ ] `./scripts/deploy.sh --app dta_blog --env beta --ref main` publishes the beta build.
- [ ] `./scripts/deploy.sh --app dta_blog --env prod --ref main` publishes the prod build.
- [ ] `https://blog.realpath.app/` serves prod HTML; view-source has article text, Tianji id `cmtvvmf562afjzqumwt1yh2y8`, and links to `https://realpath.app/`.
- [ ] `https://beta.blog.realpath.app/` serves beta HTML; Tianji id `cmtvvn6z62agdzqumtk8xijpy`; links to `https://beta.realpath.app/`; demo posts present.
- [ ] `https://blog.realpath.app/sitemap.xml` and `robots.txt` / `llms.txt` 200.
- [ ] TLS + DNS for both names. UFW only as needed for the new static ports (LAN / proxy, not world-open if NPM terminates TLS).
## Related
- [Ditch_The_Agent/dta_blog#1](https://git.aimloperations.com/Ditch_The_Agent/dta_blog/issues/1) — static blog implementation
- `dta_webapp` node-static + `roles/web-static` — copy this pattern
- Tianji already configured in the SSG; no new Tianji **server** work
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
Ditch_The_Agent/dta_blog is a static HTML/CSS RealPath blog (Python SSG, not a Vite SPA). Crawlers need real article HTML. Spin up beta and prod the same way we serve
dta_webapp(checkout → build → nginx inweb-static).Product hosts (not
realpath.app/blogsubdirectory):https://blog.realpath.apphttps://realpath.appcmtvvmf562afjzqumwt1yh2y8https://beta.blog.realpath.apphttps://beta.realpath.appcmtvvn6z62agdzqumtk8xijpyTianji script URL is already in the built HTML (
https://tianji.aimloperations.com/tracker.js). Ops does not inject ids — just serve the right--envbuild.Build
Repo:
ssh://git@git.aimloperations.com:30009/Ditch_The_Agent/dta_blog.git(branchmain).package.jsonalso hasbuild:prod/build:betathat mkdir + copy those webroots, so the existing node-static deploy path (npm cithennpm run build:<env>) can work. Build itself is Python 3 stdlib only — no pip, no Node compile.Beta build includes
demo: trueseed posts. Prod omits them.Proposed server-infra work
dta_blogtoapp_catalogininventory/group_vars/all.yml:type: node-static(reuseroles/app-deploy/tasks/node_static.yml) or a thinpython-staticvariant that runspython3 build.py --env <env>if you do not wantnpm cion a no-dep package.repo: "{{ git_base_url }}/Ditch_The_Agent/dta_blog.git"default_branch: mainwebroot_pattern: "/var/www/{env}.blog.realpath.app/html"dta_webapp) inhost_apps:Confirm these are free vs current map (dta_webapp 8080/8081, chat 8082/8083, abc_fe 8085, …). Pick neighbors if 8086/8087 clash.
web-staticnginx already doestry_files $uri $uri/ /index.html— that is enough for/<slug>/directories. Optional: adderror_page 404 /404.htmlfor this app only.realpath.app→ prod static port,beta.realpath.app→ beta static port):blog.realpath.app→ prod 8086beta.blog.realpath.app→ beta 8087IMPLEMENTATION.md/scripts/deploy.shhelp. Gitea deploy can later mirrordta_webapp(./scripts/deploy.sh --app dta_blog --env beta|prod).Do not reverse-proxy this onto
realpath.app/blogunless product changes their mind. Logo / How it Works on the blog must keep pointing at the app origin (realpath.appvsbeta.realpath.app), not at the blog host.Acceptance criteria
dta_bloginapp_catalogwith beta + prod webroots under/var/www/{env}.blog.realpath.app/html../scripts/deploy.sh --app dta_blog --env beta --ref mainpublishes the beta build../scripts/deploy.sh --app dta_blog --env prod --ref mainpublishes the prod build.https://blog.realpath.app/serves prod HTML; view-source has article text, Tianji idcmtvvmf562afjzqumwt1yh2y8, and links tohttps://realpath.app/.https://beta.blog.realpath.app/serves beta HTML; Tianji idcmtvvn6z62agdzqumtk8xijpy; links tohttps://beta.realpath.app/; demo posts present.https://blog.realpath.app/sitemap.xmlandrobots.txt/llms.txt200.Related
dta_webappnode-static +roles/web-static— copy this pattern