fix: mount custom sign-in UI over Logto experience dist
CUSTOM_UI_PATH is a Logto Cloud feature, not available in OSS. The correct approach for self-hosted Logto is to volume-mount over /etc/logto/packages/experience/dist/. - Use init container (sign-in-ui) to copy dist to shared volume as root (fixes permission denied with cameleer user) - Logto mounts signinui volume at experience/dist path - Logto depends on sign-in-ui init container completion - Remove saas-entrypoint.sh approach (no longer needed) - Revert Dockerfile entrypoint to direct java -jar - Permit /favicon.svg in SecurityConfig for sign-in page logo Tested: full OIDC flow works end-to-end via Playwright. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,6 @@ WORKDIR /app
|
|||||||
RUN addgroup -S cameleer && adduser -S cameleer -G cameleer
|
RUN addgroup -S cameleer && adduser -S cameleer -G cameleer
|
||||||
COPY --from=build /build/target/*.jar app.jar
|
COPY --from=build /build/target/*.jar app.jar
|
||||||
COPY --from=sign-in-frontend /ui/dist/ /app/sign-in-dist/
|
COPY --from=sign-in-frontend /ui/dist/ /app/sign-in-dist/
|
||||||
COPY docker/saas-entrypoint.sh /app/entrypoint.sh
|
|
||||||
RUN chmod +x /app/entrypoint.sh
|
|
||||||
USER cameleer
|
USER cameleer
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
ENTRYPOINT ["/app/entrypoint.sh"]
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||||
|
|||||||
@@ -63,15 +63,16 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
sign-in-ui:
|
||||||
|
condition: service_completed_successfully
|
||||||
entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"]
|
entrypoint: ["sh", "-c", "npm run cli db seed -- --swe && npm start"]
|
||||||
volumes:
|
volumes:
|
||||||
- signinui:/etc/logto/custom-ui
|
- signinui:/etc/logto/packages/experience/dist
|
||||||
environment:
|
environment:
|
||||||
DB_URL: postgres://${POSTGRES_USER:-cameleer}:${POSTGRES_PASSWORD:-cameleer_dev}@postgres:5432/logto
|
DB_URL: postgres://${POSTGRES_USER:-cameleer}:${POSTGRES_PASSWORD:-cameleer_dev}@postgres:5432/logto
|
||||||
ENDPOINT: ${PUBLIC_PROTOCOL:-https}://${PUBLIC_HOST:-localhost}
|
ENDPOINT: ${PUBLIC_PROTOCOL:-https}://${PUBLIC_HOST:-localhost}
|
||||||
ADMIN_ENDPOINT: http://${PUBLIC_HOST:-localhost}:3002
|
ADMIN_ENDPOINT: http://${PUBLIC_HOST:-localhost}:3002
|
||||||
TRUST_PROXY_HEADER: 1
|
TRUST_PROXY_HEADER: 1
|
||||||
CUSTOM_UI_PATH: /etc/logto/custom-ui
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3001/oidc/.well-known/openid-configuration', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))\""]
|
test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:3001/oidc/.well-known/openid-configuration', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))\""]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
@@ -121,6 +122,14 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- cameleer
|
- cameleer
|
||||||
|
|
||||||
|
sign-in-ui:
|
||||||
|
image: ${CAMELEER_IMAGE:-gitea.siegeln.net/cameleer/cameleer-saas}:${VERSION:-latest}
|
||||||
|
restart: "no"
|
||||||
|
user: root
|
||||||
|
entrypoint: ["sh", "-c", "cp -r /app/sign-in-dist/* /data/sign-in-ui/ && echo '[sign-in-ui] Copied custom UI to shared volume'"]
|
||||||
|
volumes:
|
||||||
|
- signinui:/data/sign-in-ui
|
||||||
|
|
||||||
cameleer-saas:
|
cameleer-saas:
|
||||||
image: ${CAMELEER_IMAGE:-gitea.siegeln.net/cameleer/cameleer-saas}:${VERSION:-latest}
|
image: ${CAMELEER_IMAGE:-gitea.siegeln.net/cameleer/cameleer-saas}:${VERSION:-latest}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -133,7 +142,6 @@ services:
|
|||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- jardata:/data/jars
|
- jardata:/data/jars
|
||||||
- bootstrapdata:/data/bootstrap:ro
|
- bootstrapdata:/data/bootstrap:ro
|
||||||
- signinui:/data/sign-in-ui
|
|
||||||
environment:
|
environment:
|
||||||
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-cameleer_saas}
|
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-cameleer_saas}
|
||||||
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-cameleer}
|
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-cameleer}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class SecurityConfig {
|
|||||||
.requestMatchers("/api/config").permitAll()
|
.requestMatchers("/api/config").permitAll()
|
||||||
.requestMatchers("/", "/index.html", "/login", "/callback",
|
.requestMatchers("/", "/index.html", "/login", "/callback",
|
||||||
"/environments/**", "/license", "/admin/**").permitAll()
|
"/environments/**", "/license", "/admin/**").permitAll()
|
||||||
.requestMatchers("/_app/**", "/favicon.ico", "/logo.svg", "/logo-dark.svg").permitAll()
|
.requestMatchers("/_app/**", "/favicon.ico", "/favicon.svg", "/logo.svg", "/logo-dark.svg").permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
)
|
)
|
||||||
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt ->
|
.oauth2ResourceServer(oauth2 -> oauth2.jwt(jwt ->
|
||||||
|
|||||||
Reference in New Issue
Block a user