Register dta_blog for node-static deploy (closes #29) #30
+28
-3
@@ -211,6 +211,7 @@ After Docker install, re-SSH so the `docker` group membership takes effect.
|
|||||||
| `company_site` | django (docker) | all webservers | prod | active/active behind NPM; beta port reserved |
|
| `company_site` | django (docker) | all webservers | prod | active/active behind NPM; beta port reserved |
|
||||||
| `dta_service` | django (docker) | all webservers | beta + prod | active/active behind NPM |
|
| `dta_service` | django (docker) | all webservers | beta + prod | active/active behind NPM |
|
||||||
| `dta_webapp` | node/vite static | all webservers | beta + prod | active/active; built to `/var/www/<env>.realpath.app/html`, served by web-static nginx |
|
| `dta_webapp` | node/vite static | all webservers | beta + prod | active/active; built to `/var/www/<env>.realpath.app/html`, served by web-static nginx |
|
||||||
|
| `dta_blog` | node-static (Python SSG) | all webservers | beta + prod | active/active; built to `/var/www/<env>.blog.realpath.app/html`; **own hosts** (`blog.realpath.app` / `beta.blog.realpath.app`), not `realpath.app/blog`; Tianji ids baked at build |
|
||||||
| `scha` | django (docker) | all webservers | prod | active/active behind NPM; beta port reserved |
|
| `scha` | django (docker) | all webservers | prod | active/active behind NPM; beta port reserved |
|
||||||
| `chat_web_app` | node-static (CRA) | all webservers | beta + prod | active/active; built to `/var/www/<env>.chat.aimloperations/html`, served by web-static nginx |
|
| `chat_web_app` | node-static (CRA) | all webservers | beta + prod | active/active; built to `/var/www/<env>.chat.aimloperations/html`, served by web-static nginx |
|
||||||
| `chat_backend` | django (docker) | all webservers | beta + prod | active/active behind NPM; Ollama `http://10.0.0.128:11434`; SearxNG `http://10.0.0.128:8088` (`SEARXNG_BASE_URL`) |
|
| `chat_backend` | django (docker) | all webservers | beta + prod | active/active behind NPM; Ollama `http://10.0.0.128:11434`; SearxNG `http://10.0.0.128:8088` (`SEARXNG_BASE_URL`) |
|
||||||
@@ -256,6 +257,7 @@ future beta replica.
|
|||||||
| dta_webapp (nginx) | 8081 | 8080 | all webservers |
|
| dta_webapp (nginx) | 8081 | 8080 | all webservers |
|
||||||
| chat_web_app (nginx) | 8083 | 8082 | all webservers |
|
| chat_web_app (nginx) | 8083 | 8082 | all webservers |
|
||||||
| abc_fe (nginx) | **8085** | 8084 (*not deployed*) | all webservers |
|
| abc_fe (nginx) | **8085** | 8084 (*not deployed*) | all webservers |
|
||||||
|
| dta_blog (nginx) | **8087** | **8086** | all webservers |
|
||||||
| SearxNG (LAN only) | — | **8088** | ai-server-4080 only (`searxng_stack`); not an NPM upstream |
|
| SearxNG (LAN only) | — | **8088** | ai-server-4080 only (`searxng_stack`); not an NPM upstream |
|
||||||
|
|
||||||
Host-local services on ai-server-4080 (not balanced by NPM):
|
Host-local services on ai-server-4080 (not balanced by NPM):
|
||||||
@@ -293,8 +295,10 @@ chat_backend secrets must use `SEARXNG_BASE_URL=http://10.0.0.128:8088`.
|
|||||||
`compose_profiles: [worker]` so deploy starts dj-queue with web. Other hosts
|
`compose_profiles: [worker]` so deploy starts dj-queue with web. Other hosts
|
||||||
omit profiles (web only).
|
omit profiles (web only).
|
||||||
- **node-static**: git checkout at ref → `npm ci` → `npm run build:<env>`
|
- **node-static**: git checkout at ref → `npm ci` → `npm run build:<env>`
|
||||||
(writes to the app's `webroot_pattern`, e.g. `/var/www/{env}.realpath.app/html`
|
(writes to the app's `webroot_pattern`, e.g. `/var/www/{env}.realpath.app/html`,
|
||||||
or `/var/www/{env}.chat.aimloperations/html`).
|
`/var/www/{env}.blog.realpath.app/html`, or `/var/www/{env}.chat.aimloperations/html`).
|
||||||
|
Optional catalog `error_page_404` (used by `dta_blog`) serves that file instead
|
||||||
|
of the SPA `/index.html` fallback.
|
||||||
- **web-static** role: one nginx container per app host serving the static roots
|
- **web-static** role: one nginx container per app host serving the static roots
|
||||||
on their ports (from `host_apps`); NPM balances across hosts. Before `compose up`,
|
on their ports (from `host_apps`); NPM balances across hosts. Before `compose up`,
|
||||||
removes any container currently publishing those host ports (`docker ps --filter
|
removes any container currently publishing those host ports (`docker ps --filter
|
||||||
@@ -315,6 +319,7 @@ point each domain at the backend(s):
|
|||||||
| company_site | aimloperations.com (+ www) | `adama:8000` + `roslin:8000` + `starbuck:8000` + `apollo:8000` |
|
| company_site | aimloperations.com (+ www) | `adama:8000` + `roslin:8000` + `starbuck:8000` + `apollo:8000` |
|
||||||
| dta_service | (see DTA NPM hosts) | `adama:8001` / `8011` + same on roslin / starbuck / apollo / ai-server-4080 |
|
| dta_service | (see DTA NPM hosts) | `adama:8001` / `8011` + same on roslin / starbuck / apollo / ai-server-4080 |
|
||||||
| dta_webapp | (see DTA NPM hosts) | `adama:8080` / `8081` + same on roslin / starbuck / apollo |
|
| dta_webapp | (see DTA NPM hosts) | `adama:8080` / `8081` + same on roslin / starbuck / apollo |
|
||||||
|
| dta_blog | `blog.realpath.app` (prod); `beta.blog.realpath.app` (beta). **Do not** reverse-proxy onto `realpath.app/blog` | `adama:8086` / `8087` + same on roslin / starbuck / apollo / ai-server-4080 |
|
||||||
| scha | `schawheaton.aimloperations.com`, `schawheaton.com` (+ www) | `adama:8002` + `roslin:8002` + `starbuck:8002` + `apollo:8002` (+ `ai-server-4080:8002`) |
|
| scha | `schawheaton.aimloperations.com`, `schawheaton.com` (+ www) | `adama:8002` + `roslin:8002` + `starbuck:8002` + `apollo:8002` (+ `ai-server-4080:8002`) |
|
||||||
| chat_web_app | `chat.aimloperations.com` (+ www); `beta.chat.aimloperations.com` | `adama:8082` / `8083` + same on roslin / starbuck / apollo / ai-server-4080 |
|
| chat_web_app | `chat.aimloperations.com` (+ www); `beta.chat.aimloperations.com` | `adama:8082` / `8083` + same on roslin / starbuck / apollo / ai-server-4080 |
|
||||||
| chat_backend | `chatbackend.aimloperations.com`; `beta.chatbackend.aimloperations.com` | `adama:8003` / `8013` + same on roslin / starbuck / apollo / ai-server-4080 |
|
| chat_backend | `chatbackend.aimloperations.com`; `beta.chatbackend.aimloperations.com` | `adama:8003` / `8013` + same on roslin / starbuck / apollo / ai-server-4080 |
|
||||||
@@ -337,6 +342,9 @@ point each domain at the backend(s):
|
|||||||
(keep the test/docker jobs).
|
(keep the test/docker jobs).
|
||||||
- [ ] `dta_webapp`: `npm run build:beta` / `build:prod` output to
|
- [ ] `dta_webapp`: `npm run build:beta` / `build:prod` output to
|
||||||
`/var/www/beta.realpath.app/html` / `/var/www/prod.realpath.app/html`.
|
`/var/www/beta.realpath.app/html` / `/var/www/prod.realpath.app/html`.
|
||||||
|
- [ ] `dta_blog`: `npm run build:beta` / `build:prod` output to
|
||||||
|
`/var/www/beta.blog.realpath.app/html` / `/var/www/prod.blog.realpath.app/html`
|
||||||
|
(`python3 build.py --env <env>` copies `dist/`). Default branch is `main`.
|
||||||
- [ ] `chat_web_app`: `npm run build:beta` / `build:prod` output to
|
- [ ] `chat_web_app`: `npm run build:beta` / `build:prod` output to
|
||||||
`/var/www/beta.chat.aimloperations/html` / `/var/www/prod.chat.aimloperations/html`.
|
`/var/www/beta.chat.aimloperations/html` / `/var/www/prod.chat.aimloperations/html`.
|
||||||
|
|
||||||
@@ -432,6 +440,22 @@ Companion workflows: [abc_be#22](https://git.aimloperations.com/GIS/abc_be/issue
|
|||||||
[abc_worker#27](https://git.aimloperations.com/GIS/abc_worker/issues/27),
|
[abc_worker#27](https://git.aimloperations.com/GIS/abc_worker/issues/27),
|
||||||
[abc_fe#27](https://git.aimloperations.com/GIS/abc_fe/issues/27).
|
[abc_fe#27](https://git.aimloperations.com/GIS/abc_fe/issues/27).
|
||||||
|
|
||||||
|
`dta_blog` ([#29](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/29)) —
|
||||||
|
Python SSG, **no secrets file**. `npm run build:<env>` writes
|
||||||
|
`/var/www/<env>.blog.realpath.app/html`. Prod (`:8086`) omits `demo: true` seed
|
||||||
|
posts; beta (`:8087`) includes them. Header/footer links are baked at build
|
||||||
|
(`https://realpath.app` vs `https://beta.realpath.app`); Tianji website ids
|
||||||
|
are likewise baked (`cmtvvmf562afjzqumwt1yh2y8` / `cmtvvn6z62agdzqumtk8xijpy`).
|
||||||
|
Default branch is `main`.
|
||||||
|
|
||||||
|
NPM / DNS / Cloudflare (Ansible does not manage these): `blog.realpath.app` →
|
||||||
|
`:8086`, `beta.blog.realpath.app` → `:8087`, TLS like the other RealPath names.
|
||||||
|
Do **not** mount this on `realpath.app/blog`. Static ports stay LAN / NPM-only
|
||||||
|
(UFW does not world-open 8086/8087).
|
||||||
|
|
||||||
|
Companion app ticket: [dta_blog#1](https://git.aimloperations.com/Ditch_The_Agent/dta_blog/issues/1).
|
||||||
|
Gitea deploy can later call `./scripts/deploy.sh --app dta_blog --env beta|prod`.
|
||||||
|
|
||||||
### One-time host bootstrap (per target)
|
### One-time host bootstrap (per target)
|
||||||
|
|
||||||
- [x] Gitea SSH key: the `gitea-key` role (in `site.yml`) generates a key per
|
- [x] Gitea SSH key: the `gitea-key` role (in `site.yml`) generates a key per
|
||||||
@@ -510,7 +534,8 @@ Store vault password for CI in a file readable only by the Act runner (e.g. `~/.
|
|||||||
| 10g | Register + deploy `url_shortening_service` (django, ports 8005/8015) | Done ([#22](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/22)) |
|
| 10g | Register + deploy `url_shortening_service` (django, ports 8005/8015) | Done ([#22](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/22)) |
|
||||||
| 10h | Register + deploy `college_craft` (django, ports 8006/8016) | Done ([#24](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/24)) |
|
| 10h | Register + deploy `college_craft` (django, ports 8006/8016) | Done ([#24](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/24)) |
|
||||||
| 10i | Register + deploy ABC beta (`abc_be` 8017, `abc_worker` 8018, `abc_fe` 8085) | Done ([#26](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/26)) |
|
| 10i | Register + deploy ABC beta (`abc_be` 8017, `abc_worker` 8018, `abc_fe` 8085) | Done ([#26](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/26)) |
|
||||||
| 10j | Register + deploy `print_forge` (django, ports 8007/8019) | This PR ([#27](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/27)) |
|
| 10j | Register + deploy `print_forge` (django, ports 8007/8019) | Done ([#27](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/27)) |
|
||||||
|
| 10k | Register + deploy `dta_blog` (node-static, ports 8086/8087) | This PR ([#29](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/29)) |
|
||||||
| 11 | Gitea container registry (optional) | Future |
|
| 11 | Gitea container registry (optional) | Future |
|
||||||
|
|
||||||
## Open Decisions
|
## Open Decisions
|
||||||
|
|||||||
@@ -80,6 +80,15 @@ app_catalog:
|
|||||||
webroot_pattern: "/var/www/{env}.realpath.app/html"
|
webroot_pattern: "/var/www/{env}.realpath.app/html"
|
||||||
# deploy runs `npm ci` then `npm run build:<env>`; that script writes to
|
# deploy runs `npm ci` then `npm run build:<env>`; that script writes to
|
||||||
# {{ web_static_root }}/<env>_dta_webapp (beta/prod), served by web-static.
|
# {{ web_static_root }}/<env>_dta_webapp (beta/prod), served by web-static.
|
||||||
|
dta_blog:
|
||||||
|
type: node-static
|
||||||
|
repo: "{{ git_base_url }}/Ditch_The_Agent/dta_blog.git"
|
||||||
|
default_branch: main
|
||||||
|
# Python SSG (stdlib). package.json build:<env> copies dist/ to this webroot
|
||||||
|
# so the existing node-static path (`npm ci` then `npm run build:<env>`) works.
|
||||||
|
webroot_pattern: "/var/www/{env}.blog.realpath.app/html"
|
||||||
|
# Real 404 page (not SPA index fallback). See roles/web-static nginx.conf.j2.
|
||||||
|
error_page_404: /404.html
|
||||||
scha:
|
scha:
|
||||||
type: django
|
type: django
|
||||||
repo: "{{ git_base_url }}/ai_ml_operations/scha.git"
|
repo: "{{ git_base_url }}/ai_ml_operations/scha.git"
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ host_apps:
|
|||||||
- { name: dta_service, env: beta, port: 8011 }
|
- { name: dta_service, env: beta, port: 8011 }
|
||||||
- { name: dta_webapp, env: prod, port: 8080 }
|
- { name: dta_webapp, env: prod, port: 8080 }
|
||||||
- { name: dta_webapp, env: beta, port: 8081 }
|
- { name: dta_webapp, env: beta, port: 8081 }
|
||||||
|
- { name: dta_blog, env: prod, port: 8086 }
|
||||||
|
- { name: dta_blog, env: beta, port: 8087 }
|
||||||
- { name: scha, env: prod, port: 8002 }
|
- { name: scha, env: prod, port: 8002 }
|
||||||
# optional: - { name: scha, env: beta, port: 8012 }
|
# optional: - { name: scha, env: beta, port: 8012 }
|
||||||
- { name: chat_web_app, env: prod, port: 8082 }
|
- { name: chat_web_app, env: prod, port: 8082 }
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ host_apps:
|
|||||||
- { name: company_site, env: prod, port: 8000 }
|
- { name: company_site, env: prod, port: 8000 }
|
||||||
- { name: dta_webapp, env: prod, port: 8080 }
|
- { name: dta_webapp, env: prod, port: 8080 }
|
||||||
- { name: dta_webapp, env: beta, port: 8081 }
|
- { name: dta_webapp, env: beta, port: 8081 }
|
||||||
|
- { name: dta_blog, env: prod, port: 8086 }
|
||||||
|
- { name: dta_blog, env: beta, port: 8087 }
|
||||||
- { name: dta_service, env: prod, port: 8001 }
|
- { name: dta_service, env: prod, port: 8001 }
|
||||||
- { name: dta_service, env: beta, port: 8011 }
|
- { name: dta_service, env: beta, port: 8011 }
|
||||||
- { name: scha, env: prod, port: 8002 }
|
- { name: scha, env: prod, port: 8002 }
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ host_apps:
|
|||||||
- { name: dta_service, env: beta, port: 8011 }
|
- { name: dta_service, env: beta, port: 8011 }
|
||||||
- { name: dta_webapp, env: prod, port: 8080 }
|
- { name: dta_webapp, env: prod, port: 8080 }
|
||||||
- { name: dta_webapp, env: beta, port: 8081 }
|
- { name: dta_webapp, env: beta, port: 8081 }
|
||||||
|
- { name: dta_blog, env: prod, port: 8086 }
|
||||||
|
- { name: dta_blog, env: beta, port: 8087 }
|
||||||
- { name: scha, env: prod, port: 8002 }
|
- { name: scha, env: prod, port: 8002 }
|
||||||
# optional: - { name: scha, env: beta, port: 8012 }
|
# optional: - { name: scha, env: beta, port: 8012 }
|
||||||
- { name: chat_web_app, env: prod, port: 8082 }
|
- { name: chat_web_app, env: prod, port: 8082 }
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ host_apps:
|
|||||||
- { name: dta_service, env: beta, port: 8011 }
|
- { name: dta_service, env: beta, port: 8011 }
|
||||||
- { name: dta_webapp, env: prod, port: 8080 }
|
- { name: dta_webapp, env: prod, port: 8080 }
|
||||||
- { name: dta_webapp, env: beta, port: 8081 }
|
- { name: dta_webapp, env: beta, port: 8081 }
|
||||||
|
- { name: dta_blog, env: prod, port: 8086 }
|
||||||
|
- { name: dta_blog, env: beta, port: 8087 }
|
||||||
- { name: scha, env: prod, port: 8002 }
|
- { name: scha, env: prod, port: 8002 }
|
||||||
# optional: - { name: scha, env: beta, port: 8012 }
|
# optional: - { name: scha, env: beta, port: 8012 }
|
||||||
- { name: chat_web_app, env: prod, port: 8082 }
|
- { name: chat_web_app, env: prod, port: 8082 }
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ host_apps:
|
|||||||
- { name: dta_service, env: beta, port: 8011 }
|
- { name: dta_service, env: beta, port: 8011 }
|
||||||
- { name: dta_webapp, env: prod, port: 8080 }
|
- { name: dta_webapp, env: prod, port: 8080 }
|
||||||
- { name: dta_webapp, env: beta, port: 8081 }
|
- { name: dta_webapp, env: beta, port: 8081 }
|
||||||
|
- { name: dta_blog, env: prod, port: 8086 }
|
||||||
|
- { name: dta_blog, env: beta, port: 8087 }
|
||||||
- { name: scha, env: prod, port: 8002 }
|
- { name: scha, env: prod, port: 8002 }
|
||||||
# optional: - { name: scha, env: beta, port: 8012 }
|
# optional: - { name: scha, env: beta, port: 8012 }
|
||||||
- { name: chat_web_app, env: prod, port: 8082 }
|
- { name: chat_web_app, env: prod, port: 8082 }
|
||||||
|
|||||||
@@ -30,9 +30,17 @@ server {
|
|||||||
root {{ (app_catalog[a.name].webroot_pattern | default(web_static_root ~ '/{env}_' ~ a.name)) | replace('{env}', a.env) }};
|
root {{ (app_catalog[a.name].webroot_pattern | default(web_static_root ~ '/{env}_' ~ a.name)) | replace('{env}', a.env) }};
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
|
{% if app_catalog[a.name].error_page_404 | default('') %}
|
||||||
|
error_page 404 {{ app_catalog[a.name].error_page_404 }};
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
{% else %}
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
location ~* \.(?:js|css|woff2?|png|jpg|jpeg|gif|svg|ico)$ {
|
location ~* \.(?:js|css|woff2?|png|jpg|jpeg|gif|svg|ico)$ {
|
||||||
expires 7d;
|
expires 7d;
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ Deploy applications with deploy-apps.yml.
|
|||||||
HOST Optional. Limit to one host: adama, roslin, starbuck, apollo, or ai-server-4080.
|
HOST Optional. Limit to one host: adama, roslin, starbuck, apollo, or ai-server-4080.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--app NAME App to deploy (company_site, dta_service, dta_webapp, scha, chat_web_app, chat_backend, monica_site, url_shortening_service, college_craft, print_forge, abc_be, abc_worker, abc_fe)
|
--app NAME App to deploy (company_site, dta_service, dta_webapp, dta_blog, scha, chat_web_app, chat_backend, monica_site, url_shortening_service, college_craft, print_forge, abc_be, abc_worker, abc_fe)
|
||||||
--env ENV Environment: beta or prod
|
--env ENV Environment: beta or prod
|
||||||
--ref REF Git ref/sha to deploy (default: master)
|
--ref REF Git ref/sha to deploy (default: master)
|
||||||
--check Dry run
|
--check Dry run
|
||||||
|
|||||||
Reference in New Issue
Block a user