The repository had no container image and no production-shaped serving configuration. `dist/server.mjs` is a preview server that applies neither the security headers nor the cache policy `config/hosting/` declares, so a deployment had nothing correct to run. `scripts/generate-nginx-config.ts` derives the server block from `dist/tech-log-serving-contract.json` plus the two hosting policy files, so the served headers and cache lifetimes cannot drift from what the contract declares. It emits no TLS and no proxy blocks: the edge terminates TLS and routes /api, and baking a backend address into the image would tie the bundle to one deployment. Static surfaces use `alias` because a base-path build serves /dev/assets/... out of dist/assets/..., which `root` plus URI would look for one directory too deep. The image copies that config next to the bundle and normalises permissions: the build writes config.json 0600, which nginx cannot read, so the container came up healthy and answered 403 for the one file the SPA needs to boot. index.html never referenced public/favicon.svg. The file shipped and nginx served it, but browsers asked for /favicon.ico, got a 404, and fell back to the default icon. `%BASE_URL%` rather than an absolute path so a prefixed deployment points at its own copy. development.json moves to the HTTP Studio source; the mock source has no backend to authenticate against, which is the whole point of that profile.
58 lines
1.7 KiB
JSON
58 lines
1.7 KiB
JSON
{
|
|
"realm": "tech-log",
|
|
"enabled": true,
|
|
"sslRequired": "none",
|
|
"registrationAllowed": false,
|
|
"loginTheme": "keycloak",
|
|
"accessTokenLifespan": 300,
|
|
"ssoSessionIdleTimeout": 1800,
|
|
"ssoSessionMaxLifespan": 36000,
|
|
"roles": {
|
|
"realm": [
|
|
{ "name": "studio-author", "description": "Tech Log Studio 편집 권한 (studio:read + studio:write)" }
|
|
]
|
|
},
|
|
"clients": [
|
|
{
|
|
"clientId": "tech-log-bff",
|
|
"name": "Tech Log BFF",
|
|
"description": "백엔드가 소유하는 Authorization Code 클라이언트. SPA 는 토큰을 직접 들지 않는다.",
|
|
"enabled": true,
|
|
"publicClient": false,
|
|
"secret": "CHANGE_ME_BFF_SECRET",
|
|
"standardFlowEnabled": true,
|
|
"directAccessGrantsEnabled": false,
|
|
"serviceAccountsEnabled": false,
|
|
"redirectUris": ["/login/oauth2/code/*"],
|
|
"webOrigins": ["+"],
|
|
"protocolMappers": [
|
|
{
|
|
"name": "realm-roles",
|
|
"protocol": "openid-connect",
|
|
"protocolMapper": "oidc-usermodel-realm-role-mapper",
|
|
"config": {
|
|
"claim.name": "realm_access.roles",
|
|
"jsonType.label": "String",
|
|
"multivalued": "true",
|
|
"access.token.claim": "true",
|
|
"id.token.claim": "true",
|
|
"userinfo.token.claim": "true"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"users": [
|
|
{
|
|
"username": "studio",
|
|
"enabled": true,
|
|
"emailVerified": true,
|
|
"email": "studio@tech-log.local",
|
|
"firstName": "Studio",
|
|
"lastName": "Author",
|
|
"credentials": [{ "type": "password", "value": "CHANGE_ME_STUDIO_PASSWORD", "temporary": false }],
|
|
"realmRoles": ["default-roles-tech-log", "studio-author"]
|
|
}
|
|
]
|
|
}
|