Troubleshooting
Content may include inaccuracies, outdated information, or technical errors. Users are advised to cross-check critical information before implementation.
Start with the state of the stack. Every service has a health check, and a service that never turns healthy is the one to look at first:
docker compose ps
docker compose logs -f backend
backend and api-gateway answer on /actuator/health, frontend on
/health, and keycloak on port 9000 at /health.
Sign-in redirects to localhost
The address the browser is sent to comes from the environment, not from the
request. APPLICATION_URL, API_GATEWAY_URL, OAUTH2_ISSUER_URL,
OAUTH2_AUTHORIZATION_URL and OAUTH2_ACCOUNT_URL must all be the public
addresses of your installation. If any of them still says localhost, users
outside the host end up at a page they cannot reach.
Keycloak reports an invalid redirect URI
The architeezy client accepts exactly one redirect URI, fixed when the realm
was first imported: API_GATEWAY_URL/login/oauth2/code/keycloak. Changing
API_GATEWAY_URL later does not change the client. Open Clients →
architeezy in the Keycloak admin console and correct Valid redirect URIs
and Valid post logout redirect URIs by hand.
The API gateway cannot reach Keycloak
OAUTH2_TOKEN_URL, OAUTH2_JWK_SET_URL and OAUTH2_USER_INFO_URL are called
by the application itself, not by the browser, and must resolve from inside the
container network - http://keycloak:8080/... in the bundled setup. A public
HTTPS address works too, as long as the container can reach it.
If OAUTH2_JWK_SET_URL is wrong, the backend cannot verify tokens and every API
call comes back as 401 even though sign-in appeared to succeed.
CORS errors in the browser console
The API gateway allows APPLICATION_URL, ABOUT_URL and APPLICATIONS_URL as
origins. Add any other origin to ALLOWED_ORIGINS, or match it with
ALLOWED_ORIGIN_PATTERNS, and restart the API gateway. That covers a second
host name for the same instance, an embedded page, and an application of your
own calling the API.
The backend cannot connect to the database
SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD come from
DATABASE_USERNAME and DATABASE_PASSWORD, which is also what the db
container is initialised with. PostgreSQL only reads those on the first start
against an empty volume: change DATABASE_PASSWORD afterwards and the database
keeps the old one while the backend presents the new one.
Either change the password inside the database with ALTER USER, or start over
with an empty volume - which deletes the data, so take a dump first.
User sessions end unexpectedly
Sessions are kept in Redis and disappear if redis was recreated without its
volume, or if REDIS_PASSWORD no longer matches what the API gateway sends.
If sessions instead expire sooner than expected, compare SESSION_TIMEOUT with
SSO Session Idle in the Keycloak realm. Both are 30 days as delivered, and
the shorter of the two wins.
Links come back as http:// behind HTTPS
The application, the API gateway and Keycloak all build their URLs from the
forwarded headers. A reverse proxy in front of them must set Host,
X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Port. The configuration
on the prebuilt images page sets all four.
Diagrams stop updating until the page is reloaded
Live updates run over a WebSocket on /subscriptions. A proxy that does not
pass Connection: upgrade and Upgrade: $http_upgrade closes it. The sample
configuration sets both, together with a long proxy_read_timeout, which the
connection needs to stay open.
Uploading a large file fails
Three limits apply in sequence:
- the reverse proxy in front of the stack;
- the frontend container, which accepts up to 100 MB;
- the backend, which accepts up to 256 MB per file.
The sample proxy configuration allows 50 MB - raise client_max_body_size there
if you need more.
A port is already in use
Every published port is set by a variable in the .env file - FRONTEND_PORT,
KEYCLOAK_PORT, DATABASE_PORT, REDIS_PORT and KEYCLOAK_DATABASE_PORT.
Change the value and run docker compose up -d again. All of them are bound to
127.0.0.1, so a conflict is always with something else on the same host.
The AI assistant does not answer
The backend talks to an OpenAI-compatible service at OPENAI_URL, which points
at host.docker.internal:11434 by default - a model server running on the host
machine. If nothing listens there, the assistant fails while the rest of the
application keeps working. Point OPENAI_URL, OPENAI_API_KEY and
OPENAI_MODEL at the service you use.