Full Standalone Deployment
The full standalone setup consists of a frontend and a single standalone backend.
The architecture is shown in the following figure.

Please also have a look into the architecture and authentication documentation.
A note about Docker
If you happen to work behind a proxy server, then you might have already configured a proxy for both http & https. In such a case, you'll have to bypass the proxy settings for keycloak.localhost (as shown in the image below), because the frontend needs to complete the sign-in process with Keycloak.

Example Setup
The docs/deployment/full-standalone directory contains a Docker Compose file with an example system consisting of all components needed in a full standalone setup.
CAUTION
The Docker Compose setup shown here contains publicly known passwords and secrets. Please don't use it in production without changes.
NOTE
You will need about 16 GB of RAM to be able to run the example smoothly.
NOTE
The example setup uses the default context path /fhir. Currently the UI only works with that default context path.
NOTE
This example setup is for a developer's machine (on localhost) and things may be different on a real virtual machine.
Create two entries in your /etc/hosts (C:\Windows\System32\Drivers\Etc\hosts on Windows):
127.0.0.1 blaze.localhost
127.0.0.1 keycloak.localhostThese subdomains of localhost are used as virtual hosts of the nginx ingress container. They ensure that Keycloak and Blaze are separated properly. Other hostnames can be used, but have to be changed everywhere in this setup.
Before you can start the system, you have to generate certificates for the ingress component. To do so, please go into the base directory of this Blaze repository and run:
make build-ingressTwo certificates and one trust store should be generated in the modules/ingress directory. The files will be referenced from that directory, you don't have to copy them.
After you have created the certificates, you can start the system by going into the docs/deployment/full-standalone directory and run:
docker compose up -d keycloakfirst, because it needs to be fully started before the Blaze components can start to avoid waiting an additional minute for Blaze fetching the Keycloak config again. After Keycloak runs, start the rest of the components:
docker compose up -dWatch all components to start completely by looking into the log output:
docker compose logs -fIn your browser, please go to https://blaze.localhost/fhir.
IMPORTANT
You have to accept certificate violations in your browser twice, once for the blaze.localhost domain and once for the keycloak.localhost domain.
You should see a big button with the text "Sign in with Keycloak":

Press it and you will be redirected to the Keycloak sign-in page:

Enter username "john" and password "insecure" and press "Sign In". After that you will be redirected to the home page:

In the top right, you will see the user menu were you can sign out again.

Performing Authorized API Requests
After the UI works, with authentication via Keycloak, we need to be able to perform authorized API requests via curl and blazectl. Other REST API clients should work similar.
For API requests OAuth 2 Client Credentials Grant should be used in order to obtain an access token. The bash script docs/deployment/full-standalone/fetch-access-token.sh can be used to fetch an access token. By default, it uses the client account present in the example keycloak config.
Now that we are able to obtain an access token, we can use curl to count the number of resources available in Blaze:
curl -sk --oauth2-bearer "$(./fetch-access-token.sh)" 'https://blaze.localhost/fhir?_summary=count'After that works, we can also use blazectl to do the same:
IMPORTANT
You need at least blazectl v0.14.0.
blazectl -k --server https://blaze.localhost/fhir --token "$(./fetch-access-token.sh)" count-resourcesLast but not least, we can import data using blazectl:
blazectl -k --server https://blaze.localhost/fhir --token "$(./fetch-access-token.sh)" upload ../../../.github/test-data/syntheaAfter importing data, we should see resource counts also in the UI:

Docker Compose Components Explained
Ingress
An nginx server is used as the ingress component. You should see the configuration of the nginx as guideline and example and not use it 1:1 in production.
ingress:
image: "nginx:1.27.2"
environment:
BLAZE_HOST: "blaze.localhost"
KEYCLOAK_HOST: "keycloak.localhost"
ports:
- "443:443"
volumes:
- "../../../modules/ingress/default.conf.template:/etc/nginx/templates/default.conf.template:ro"
- "../../../modules/ingress/blaze-cert.pem:/etc/nginx/conf.d/blaze-cert.pem:ro"
- "../../../modules/ingress/blaze-key.pem:/etc/nginx/conf.d/blaze-key.pem:ro"
- "../../../modules/ingress/keycloak-cert.pem:/etc/nginx/conf.d/keycloak-cert.pem:ro"
- "../../../modules/ingress/keycloak-key.pem:/etc/nginx/conf.d/keycloak-key.pem:ro"The two environment variables BLAZE_HOST and KEYCLOAK_HOST are used in the modules/ingress/default.conf.template file. The entrypoint of the nginx container will expand the template into the actual /etc/nginx/conf.d/default.conf file.
The two separate virtual hosts are used to separate the Blaze web origin from that of Keycloak. Separating both web origins is important for security. Otherwise cookies might be visible between both the Blaze and Keycloak web UI. In a production setup it's recommended to further separate the Keycloak installation from that of Blaze. Keycloak should be part of your general IT infrastructure and not part of Blaze.
The other mounted files are the certificates and private keys for the two virtual hosts.
More in depth information about the nginx configuration can be found in the README of the ingress module.
Frontend
The frontend of Blaze runs as separate container. It will talk to the backend directly over HTTP inside the Docker network and to Keycloak over HTTPS. It is stateless and scaled to multiple instances. Scaling the backend in documented here.
frontend:
image: "samply/blaze-frontend:1.13.0@sha256:f613391e0eb4eb35cb67d46f3e869b6009b691f738a7573e75222253666e4805"
environment:
BACKEND_BASE_URL: "http://backend:8080"
AUTH_CLIENT_ID: "account"
AUTH_CLIENT_SECRET: "e11a3a8e-6e24-4f9d-b914-da7619e8b31f"
AUTH_ISSUER: "https://keycloak.localhost/realms/blaze"
AUTH_SECRET: "666df42c74ce1f4728fe2ffe99b146e0f2e4b4f9810594fcf68c0330495bca0f"
PROTOCOL_HEADER: "x-forwarded-proto"
HOST_HEADER: "x-forwarded-host"
NODE_EXTRA_CA_CERTS: "/app/keycloak-cert.pem"
extra_hosts:
- "keycloak.localhost:host-gateway"
volumes:
- "../../../modules/ingress/keycloak-cert.pem:/app/keycloak-cert.pem:ro"
healthcheck:
test: [ "CMD", "wget", "--spider", "http://127.0.0.1:3000/fhir/" ]
interval: 10s
timeout: 5s
retries: 5
start_period: 30sIMPORTANT
Please remove the extra_hosts key if you use an external running Keycloak instance.
The documentation of the environment variables can be found here.
CAUTION
Please don't use the same secrets in production.
Backend
backend:
image: "samply/blaze:1.13.0@sha256:808d04a6224ca926ab2422d4235cd008399b5e4d4f5855d52fd2715de295f1c2"
environment:
JAVA_TOOL_OPTIONS: "-Xmx2g"
LOG_LEVEL: "debug"
ENABLE_ADMIN_API: "true"
OPENID_PROVIDER_URL: "https://keycloak.localhost/realms/blaze"
OPENID_CLIENT_TRUST_STORE: "/app/keycloak-trust-store.p12"
OPENID_CLIENT_TRUST_STORE_PASS: "insecure"
extra_hosts:
- "keycloak.localhost:host-gateway"
volumes:
- "blaze-data:/app/data"
- "../../../modules/ingress/keycloak-trust-store.p12:/app/keycloak-trust-store.p12:ro"
healthcheck:
test: [ "CMD", "wget", "--spider", "http://localhost:8080/health" ]
interval: 10s
timeout: 5s
retries: 5
start_period: 30sIMPORTANT
Please remove the extra_hosts key if you use an external running Keycloak instance.
Important environment variables are ENABLE_ADMIN_API and OPENID_PROVIDER_URL. Both are feature toggles that enable features needed by the frontend. The OPENID_PROVIDER_URL should be set to the same value as AUTH_ISSUER at the frontend. The OPENID_CLIENT_TRUST_STORE is only needed if the server certificate of Keycloak isn't signed by a standard certificate authority. The file keycloak-trust-store.p12 is generated in the ingress module. You can use similar scripts to generate the trust store in your environment. Full documentation of the environment variables can be found here.
Without Login Since 1.14.0
For a demo server, the frontend can be deployed without login by setting ENABLE_AUTH to false. Keycloak isn't needed then and the AUTH_* environment variables can be omitted:
frontend:
environment:
BACKEND_BASE_URL: "http://backend:8080"
ENABLE_AUTH: "false"
PROTOCOL_HEADER: "x-forwarded-proto"
HOST_HEADER: "x-forwarded-host"Without login, the admin section of the frontend is removed, because everybody could use it. The backend has to run without OPENID_PROVIDER_URL, because the frontend sends its requests without an access token. Please also don't set ENABLE_ADMIN_API at the backend, because its admin API would be reachable without login as well.
Without login, API requests carry no access token, so the ingress can't tell them apart from the requests of browsers by the Authorization header. Use modules/ingress/no-auth.conf.template instead of modules/ingress/default.conf.template. It forwards requests accepting application/fhir+json or application/fhir+xml to the backend and all others to the frontend. API clients have to send one of these two media types in the Accept header, which blazectl does.
CAUTION
Without OPENID_PROVIDER_URL, everybody can read and write all data via the FHIR API of the backend. Please only use this setup with data that may be public.
Health Check
Frontend
The command wget is available in the Blaze frontend image and can be used for implementing a health check on the /fhir/ path at port 3000. Use the IPv4 address 127.0.0.1 instead of localhost, because the frontend listens only on IPv4 by default, while localhost may resolve to the IPv6 address ::1 inside the container.
Backend
The command wget is available and can be used for implementing a health check on the /health endpoint which is separate from the /fhir endpoint.
NOTE
The command curl is not available in the Blaze backend image. Please use wget instead.
Keycloak Auth Provider
For Keycloak the realm docs/deployment/full-standalone/keycloak/import/realm-blaze.json is imported at startup. It contains a client with the name account and secret e11a3a8e-6e24-4f9d-b914-da7619e8b31f and a user with name john and password insecure.
CAUTION
Please don't use this realm in production.
As you can see in the realm-blaze.json file, the redirect URL for the client is set to https://blaze.localhost/fhir/auth/callback/keycloak. You have to change the redirect URL if you use a different hostname.
If your users immediately sign-in after clicking on the Sign in with Keycloak button, the Keycloak session still exists and so Keycloak will sign in the user automatically without requiring credentials. If ou like to disable the Keycloak sessions, you can open the Keycloak Admin UI and go to Authentication -> browser flow and disable the Cookie step.
On top of the realm an admin user with name admin and password admin is configured. You can go to https://keycloak.localhost/admin and modify settings. More in-depth configuration of Keycloak it out of scope of the Blaze documentation.
keycloak:
image: "quay.io/keycloak/keycloak:26.4.2"
command: "start --import-realm --hostname=keycloak.localhost --proxy-headers forwarded --http-enabled true"
environment:
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
volumes:
- "./keycloak/import:/opt/keycloak/data/import"