-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathjac.toml
More file actions
171 lines (161 loc) · 8.67 KB
/
Copy pathjac.toml
File metadata and controls
171 lines (161 loc) · 8.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
[project]
name = "jaseci-blogs"
version = "0.1.0"
description = "The Jaseci & Jac engineering blog — editorial home for jaseci.org writing."
[serve]
base_route_app = "app"
cl_route_prefix = "/"
# CONFIG NAMESPACE: everything below is [client.*] / [scale.*], NOT
# [plugins.client.*] / [plugins.scale.*]. The one-binary toolchain folded jac-scale
# and jac-client into jaclang core, and the old `[plugins.<name>]` paths NO LONGER
# PARSE — they are silently ignored, with no error, falling back to defaults. On
# this app that would deploy `jaseci-blogs` into namespace `default` with no ALB
# ingress, no domain, no Mongo/Redis and none of the submission-portal secrets. If a
# deploy ever logs the wrong app or namespace in its "Deploying application …" line,
# check this prefix first.
#
# Dropped in the migration, deliberately:
# - `[plugins.client] enabled` / `[plugins.scale] enabled` — there is nothing to
# enable now that both are in core; declaring any [scale.*] section is what opts
# in, and client bundling is detected from the source.
# - `[plugins.client] debug = false` — not a key on the new client config. The
# production single-origin behaviour it selected (one server for the bundled
# client + static public/) is what `jac start` does without `--dev`.
# - `[plugins.client.paths]` (@components/*, @styles/*) — dead config: no file in
# this repo imports either alias (verified by grep), so it is not carried across
# to a new key name that cannot be verified.
# Default <head> for the generated SPA shell. Without this, only <title>app</title>
# is emitted with no meta, so non-JS crawlers (LinkedIn, Slack, Twitter) render a
# blank "app" card. Site-wide default only (same for every URL); real browsers still
# get per-page title/og from set_social_meta JS. Per-post cards FOR CRAWLERS still
# need an edge dynamic-rendering layer — there is no SSR.
#
# Only fields that survived the old jac-client unquoted-attribute bug are set here
# (`content=Foo Bar` truncated at the first space, so any multi-word value broke).
# `title` is element text and renders in full. `description` is documented as
# supported on the new toolchain and would be worth re-adding — once a deploy
# confirms attribute values are quoted now. `og_image` is not in the documented key
# list; it is retained because it is harmless if ignored.
[client.app_meta_data]
title = "Jaseci Blogs — engineering writing from the Jaseci & Jac ecosystem"
theme_color = "#b54a1a"
og_image = "https://www.jaseci.org/images/logo.png"
# Scale owns the submission portal's session JWT (it signs/validates the token the
# browser sends as `Authorization: Bearer` on every walker call). The app does not
# hand-roll JWTs. The secret itself is delivered through [scale.secrets] below,
# which is the documented path; this section only tunes algorithm and lifetime.
[scale.jwt]
secret = "${JWT_SECRET}"
algorithm = "HS256"
exp_delta_days = 7
[scale.kubernetes]
app_name = "jaseci-blogs"
namespace = "jaseci-blogs"
# The bundle PVC that carries the jac binary + app code to the pods is
# ReadWriteMany. This cluster's default class (gp3, ebs.csi.aws.com) is RWO and
# rejects RWX with "Volume capabilities not supported", which leaves the
# bundle-loader pod Pending until the deploy times out. efs-sc (efs.csi.aws.com) is
# the cluster's RWX class. The newsletter app hit exactly this on its own migration
# and pins the same class; jacBuilder pins it too.
bundle_storage_class = "efs-sc"
liveness_initial_delay = 300
liveness_failure_threshold = 10
readiness_initial_delay = 60
# Posts/authors are parsed from disk, but the submission portal persists shareable
# draft previews (PreviewDoc nodes on the shared public root), which must survive
# restarts and be consistent across replicas. Mongo + Redis are auto-provisioned as
# StatefulSets with generated credentials, and persist across app redeploys.
mongodb_enabled = true
redis_enabled = true
# The client bundle is built with vite/bun inside the pod, which is memory- and
# CPU-hungry: a 512Mi limit OOM-kills the build (exit 137). Limits must cover the
# build peak even though steady-state serving is light; requests stay modest (the
# build is a short burst) and let the HPA read CPU%.
cpu_request = "250m"
cpu_limit = "1500m"
memory_request = "512Mi"
memory_limit = "3Gi"
# Attach to the cluster's shared AWS ALB (group jaseci-cluster-alb-2) instead of
# standing up a dedicated NGINX controller + NLB per app. The ALB terminates TLS via
# the ACM cert, so cert-manager is not required and the two-step --enable-tls flow
# in the deploy guide does not apply here.
shared_ingress = true
shared_ingress_class = "alb"
shared_ingress_tls = true
domain = "blogs.jaseci.org"
[scale.kubernetes.shared_ingress_annotations]
"alb.ingress.kubernetes.io/scheme" = "internet-facing"
"alb.ingress.kubernetes.io/target-type" = "ip"
"alb.ingress.kubernetes.io/group.name" = "jaseci-cluster-alb-2"
"alb.ingress.kubernetes.io/certificate-arn" = "arn:aws:acm:us-east-2:776241927220:certificate/642526d6-00ee-4394-970d-89d5dc898906"
"alb.ingress.kubernetes.io/listen-ports" = '[{"HTTP": 80}, {"HTTPS": 443}]'
"alb.ingress.kubernetes.io/ssl-redirect" = "443"
[scale.secrets]
PUBLIC_SITE_URL = "https://blogs.jaseci.org"
# Submission portal credentials. ${...} is resolved from the deploy-time
# environment (the GitHub Actions runner — see deploy.yml) into the
# jaseci-blogs-secrets k8s Secret, never committed. Blank values are tolerated:
# the /submit + /reviewer features simply report "not configured" until set.
# Only an OAuth App is needed — every GitHub action runs as the signed-in user
# (fork + PR). See .github/SUBMIT_FLOW.md for the one-time setup.
GH_REPO = "jaseci-labs/jaseci-blogs"
GH_BASE_BRANCH = "main"
GH_OAUTH_CLIENT_ID = "${GH_OAUTH_CLIENT_ID}"
GH_OAUTH_CLIENT_SECRET = "${GH_OAUTH_CLIENT_SECRET}"
# Scale signs the session JWT with this — the default is forge-able, so it must be
# set in prod.
JWT_SECRET = "${JWT_SECRET}"
# Fernet key for the GitHub token at rest (the browser holds only ciphertext).
SUBMIT_SESSION_SECRET = "${SUBMIT_SESSION_SECRET}"
[dependencies]
# The toolchain is the one-binary `jac`: `jac-scale` and `jac-client` no longer
# exist as packages, so the old pins ("jac-scale[deploy,data]" == 0.2.23 and
# jac-client == 0.3.21, held back because newer releases crash-looped the pod's
# boot-time binary installer) are gone with the problem they worked around — pods
# no longer fetch a toolchain from GitHub Releases at all. Scale's optional heavy
# deps (pymongo, redis, kubernetes, docker) are resolved by `jac install` from the
# [scale.*] config above.
markdown = ">=3.5"
pyyaml = ">=6.0"
pygments = ">=2.17"
# Submission portal: GitHub API calls + Fernet encryption of the GitHub token.
requests = ">=2.31"
cryptography = ">=42.0"
# WORKAROUND for an upstream gap, not an app dependency — nothing in this repo
# imports dotenv. jaclang's Kubernetes realizer does, at module scope
# (jaclang/scale/runtime/realizer/kubernetes_realizer.jac:3 —
# `import from dotenv { load_dotenv }`), but neither the shipped runtime nor
# `jac install --scale` installs python-dotenv, so `jac start --scale` dies with
# ModuleNotFoundError before it reaches the cluster. Declaring it here puts it in
# .jac/venv, which is on the import path for the deploy. Drop this once jaclang
# declares its own scale dependency.
python-dotenv = ">=1.0"
# WORKAROUND, same class as python-dotenv above: the migrated main-deployment
# pod serves with a redis handle of None ("Redis connection failed: 'NoneType'
# object has no attribute 'from_url'" on every healthz probe) because redis-py
# never reaches the serving env, despite [scale.redis] being enabled and
# REDIS_URL being set. Every shared-root WRITE then throws: CreatePreview 500s
# (the visible symptom) and RecordView/RecordEngagement swallow the same error
# and report ok:false, so analytics have been silently dead since the
# migration. Shared-root READS (Mongo) still work, which is why old preview
# links resolve. Declaring redis here lands it in the same env that already
# provides requests/cryptography at runtime. Drop once `jac install` actually
# resolves it from [scale.*].
redis = ">=5.0"
[dependencies.npm]
react = "^18.2.0"
react-dom = "^18.2.0"
react-router-dom = "^6.22.0"
react-error-boundary = "^5.0.0"
# The client runtime's form layer moved from react-hook-form to @tanstack/react-form.
# Neither is imported by anything in this repo — they are runtime-level deps, so the
# swap follows the runtime, not our source. react-hook-form and @hookform/resolvers
# are dropped with it.
"@tanstack/react-form" = "^1.33.2"
zod = "^4.3.6"
[dependencies.npm.dev]
vite = "^6.4.1"
"@vitejs/plugin-react" = "^4.2.1"
typescript = "^5.3.3"
"@types/react" = "^18.2.0"
"@types/react-dom" = "^18.2.0"