Skip to main content

After pulling and running Indicium and Universal containers in Docker on an on-premise Ubuntu host both are running but Universal isn’t reachable via the browser. Browsing to http://hostname/ shows the running Indicium instance (log-in also works) but when going to http://hostname/alias our end-product doesn’t start and I get a blank page instead.

These are the docker run commands I used to pull and install the containers:

 

Indicium

docker run \
    -p 8080:8080 \
    -e SQL_USERNAME='***' \
    -e SQL_PASSWORD='***' \
    -e CUSTOM_JSON='{"Logging":{"LogLevel":{"Default":"Information","System":"Information","Microsoft":"Warning","Indicium":"Information","Duende.IdentityServer":"Warning"},"ApplicationInsights":{"LogLevel":{"Default":"Information","System":"Information","Microsoft":"Warning","Indicium":"Information","Duende.IdentityServer":"Warning"}},"ErrorLog":{"PathFormat":"Indicium-{Date}.txt","LogLevel":{"Default":"Error"}}},"MetaSourceConnection":{"Server":"HOST1","Database":"IAM"},"Agent":{"Enabled":false}}' \
    --add-host HOST1:192.168.100.1 \
    --add-host HOST2:192.168.100.2 \
    --add-host HOST3:192.168.100.3 \
    --add-host HOST4:192.168.100.4 \
    --network="host" \
    registry.thinkwisesoftware.com/public/indicium:2023.3

 

Universal

docker run \
    -p 8080:8080 \
    -e SERVICE_URL='http://localhost/indicium/iam/iam' \
    registry.thinkwisesoftware.com/public/universal:2023.3

 

Without the option network=”host” Indicium can’t reach SQL Server on another machine in the network. I’m not sure why this is the case.

I’ve tried both ports 80 and 8080. 80 works but returns a blank page while 8080 returns an error that the browser is unable to connect.

What’s the correct URL for the Universal GUI?

After pulling and running Indicium and Universal containers in Docker on an on-premise Ubuntu host both are running but Universal isn’t reachable via the browser. Browsing to http://hostname/ shows the running Indicium instance (log-in also works) but when going to http://hostname/alias our end-product doesn’t start and I get a blank page instead.

These are the docker run commands I used to pull and install the containers:

 

Indicium

docker run \
    -p 8080:8080 \
    -e SQL_USERNAME='***' \
    -e SQL_PASSWORD='***' \
    -e CUSTOM_JSON='{"Logging":{"LogLevel":{"Default":"Information","System":"Information","Microsoft":"Warning","Indicium":"Information","Duende.IdentityServer":"Warning"},"ApplicationInsights":{"LogLevel":{"Default":"Information","System":"Information","Microsoft":"Warning","Indicium":"Information","Duende.IdentityServer":"Warning"}},"ErrorLog":{"PathFormat":"Indicium-{Date}.txt","LogLevel":{"Default":"Error"}}},"MetaSourceConnection":{"Server":"HOST1","Database":"IAM"},"Agent":{"Enabled":false}}' \
    --add-host HOST1:192.168.100.1 \
    --add-host HOST2:192.168.100.2 \
    --add-host HOST3:192.168.100.3 \
    --add-host HOST4:192.168.100.4 \
    --network="host" \
    registry.thinkwisesoftware.com/public/indicium:2023.3

 

Universal

docker run \
    -p 8080:8080 \
    -e SERVICE_URL='http://localhost/indicium/iam/iam' \
    registry.thinkwisesoftware.com/public/universal:2023.3

 

Without the option network=”host” Indicium can’t reach SQL Server on another machine in the network. I’m not sure why this is the case.

I’ve tried both ports 80 and 8080. 80 works but returns a blank page while 8080 returns an error that the browser is unable to connect.

What’s the correct URL for the Universal GUI?

In your example both host ports are 8080, if this is on the same server this cannot work. Then Universal should be 80:8080 for example and indicium 8080:8080   


In your example both host ports are 8080, if this is on the same server this cannot work. Then Universal should be 80:8080 for example and indicium 8080:8080   

Hi Freddy!

Valid point. I had tried different ports already: 8080:8080 for Indicium and 8081:8080 for Universal but the problem was the same. The documentation mentions 8080:8080 for both containers which I did find strange but something I ended up trying regardless.

Something else I don’t understand is that according to “docker container ls -a” the Universal container also listens on port 80, something I haven’t even configured:

 

 

And when I try to create the Universal container with port 80:8080 I get an error message. With only the Indicium container active the command “ss -tunlp” generates this output:

 

 

Somehow the Indicium container already takes up port 80 on the host despite it being generated with port 8080:8080.

I'm still trying to grasp what’s happening here. The host is a fresh Ubuntu 24.04 LTS headless installation. Pretty standard stuff.


​Hi ​@Roland, container images starting from 2025.1 are using the port 8080, any older images are still using port 80. If needed, this can be made more clear in the documentation.

I noticed you are using 2023.3, so you should still use port 80.

You can verify what port an image exposes with the command docker inspect.

For example,

docker inspect registry.thinkwisesoftware.com/public/universal:2023 | grep -A 2 ExposedPorts

This will display the following output,

"ExposedPorts": {
    "80/tcp": {}
},

When the same command is applied to the image with 2025, you will get this output,

"ExposedPorts": {
    "8080/tcp": {}
},

 

As for network=host, this option removes the isolation between the container and the host by using the host networking directly, which gives access to the host DNS.

If you are connecting to a database server outside the Docker network through a DNS name instead of IP, and it does not work without explicitly specifying the host network mode, there might be a mistake in the --add-host flag.

For troubleshooting networking issues, for example DNS resolution, I personally use the following container image: https://github.com/nicolaka/netshoot.

I hope this helps you further.


Hi ​@Leon Kroon,

Running docker inspect on the Indicium container returns this output:

"ExposedPorts": {
                "80/tcp": {},
                "8080/tcp": {}

Indicium however is only reachable via port 80.

I’ve now removed and recreated the container without any of the network=host and add-host parmeters and chose to fill the IP address as the SQL Server address instead and it now connects to SQL Server just fine. The SQL Server host name contains a hyphen so maybe it was a matter of syntax. For now I’ll stick to using the IP address instead.

Unfortunately it seems to make matters worse because with this setup Indicium can’t be reached from a browser any longer. When going to http://dockermachine/ the browser is redirected to https://dockermachine/ and then quickly shows an “unable to connect” message. That last step makes sense as no container is listening on port 443 but I don’t understand this redirection in the first place.

Small update
I’ve recreated the Indicium container using port 80:8080. Docker inspect still returns ports 80 and 8080 but according to ss Indicium is only listening on port 80. The redirect to https:// (port 443) no longer happens but I still get an “ unable to connect”.


Hi ​@Leon Kroon,

Running docker inspect on the Indicium container returns this output:

"ExposedPorts": {
                "80/tcp": {},
                "8080/tcp": {}

Indicium however is only reachable via port 80.

I’ve now removed and recreated the container without any of the network=host and add-host parmeters and chose to fill the IP address as the SQL Server address instead and it now connects to SQL Server just fine. The SQL Server host name contains a hyphen so maybe it was a matter of syntax. For now I’ll stick to using the IP address instead.

Unfortunately it seems to make matters worse because with this setup Indicium can’t be reached from a browser any longer. When going to http://dockermachine/ the browser is redirected to https://dockermachine/ and then quickly shows an “unable to connect” message. That last step makes sense as no container is listening on port 443 but I don’t understand this redirection in the first place.

Small update
I’ve recreated the Indicium container using port 80:8080. Docker inspect still returns ports 80 and 8080 but according to ss Indicium is only listening on port 80. The redirect to https:// (port 443) no longer happens but I still get an “ unable to connect”.

I don't think these containers are really made for direct access, but to be placed behind a reverse proxy like NGINX. There you can handle the http(s) stuff and let the / endpoint point to the Universal container and the /indicium (or whatever you call it) to the Indicium container. 

We use containers as well, but all behind a reverse proxy and the Universal GUI we host directly via vhosts on NGINX. That way you can also better secure any connection with security headers, although you can probably also do this within the Universal container, but that I never tried or researched. 


I’ve made some progress. I recreated the Indicium container with this command:

docker run \
    -p 8080:80 \
    -d \
    -e SQL_SERVER='192.168.XXX.XXX' \
    -e SQL_DATABASE='IAM' \
    -e SQL_USERNAME='***' \
    -e SQL_PASSWORD='***' \
    -e CUSTOM_JSON='{"Agent":{"Enabled":false}}' \
    registry.thinkwisesoftware.com/public/indicium:2023.3

Now Indicium can be reached from outside the container via http://dockermachine:8080.

Next up I recreated the Universal container:

docker run \
    -p 80:80 \
    -d \
    -e SERVICE_URL='http://localhost:8080' \
    --network="host" \
    registry.thinkwisesoftware.com/public/universal:2023.3

When I do curl localhost:8080 inside the Universal container I get the HTML source code of the Indicium login page which suggests that Universal should be able to talk to Indicium. Yet when I browse to http://dockermachine and fill localhost:8080 (or the actual machine name instead of localhost, same result) as the meta server URL I get a meta server is not reachable message. Removing the network="host" parameter doesn’t change this behavior.

It seems I am almost there though.


Hi ​@Leon Kroon,

Running docker inspect on the Indicium container returns this output:

"ExposedPorts": {
                "80/tcp": {},
                "8080/tcp": {}

Indicium however is only reachable via port 80.


Hi ​@Roland, my bad, I forgot it is possible to both inspect running/stopped containers and container images. When you inspect a container created with -p 100:100 -p 200:200, it will show port 80, 100 and 200 as exposed ports.

When you inspect an image, it will only show the exposed ports according to the Dockerfile we created it with.

 

I don't think these containers are really made for direct access, but to be placed behind a reverse proxy like NGINX. There you can handle the http(s) stuff and let the / endpoint point to the Universal container and the /indicium (or whatever you call it) to the Indicium container. 

 

This is correct. For as far as I know, it even is impossible to get a working environment with containers without a reverse proxy, unless Indicium is put in develop mode (which is not recommended). Indicium rejects any requests not originating from the same domain and port by default due to CORS. This is also the reason you see the error Meta server is not reachable. Contact your administrator.
This can be verified when you open the Web Developer Tools.
 

 

Without a reverse proxy, you will not be able to achieve the following things;

  • Secure connection with TLS certificates
  • Indicium on the same domain and port, by making Indicium reachable at /indicium
  • Universal and Indicium reachable on the default HTTPS port, 443
  • Place and/or pass HTTP headers

To solve this issue, you need to implement a reverse proxy. We have an example on how to use Traefik as reverse proxy with a Compose-file in our documentation, maybe this will help you further: https://docs.thinkwisesoftware.com/docs/deployment/container_deployment_docker_compose


@Leon Kroon Thank you! This was the information I needed to get to a working environment. I added a few extra environment variables and successfully created all required containers. We can now use our end-product via the Docker machine. This reverse proxy method actually turned out to be quite straightforward. And it allows running multiple environments side by side on the same machine which will probably prove to be a useful feature.


I decided to run a second Indicium container on the same machine. My thought was to make it listen via a different path (/indicium_dev instead of /indicium) by renaming indicium: and all its labels (including the path prefix) to indicium_dev. But after composing the containers both the original indicium and the new indicium_dev don’t respond in the browser. There seems to be a conflict in the traefik setup. What’s the correct way to add a second Indicium instance to docker-compose.yaml?


Hi ​@Roland, I personally use the following configuration whenever I test with multiple Indicium instances;

---
services:
proxy:
image: traefik
ports:
- 80:80
- 443:443
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
# Enable to see access logs in the Traefik standard output
# - "--accesslog=true"
# Enable to set logging level to Debug
# - "--log.level=DEBUG"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"

universal_iam:
image: registry.thinkwisesoftware.com/public/universal:${TAG}
environment:
- SERVICE_URL=https://${EXTERNAL_HOST}/indicium/iam/iam
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend_iam.rule=Host(`${EXTERNAL_HOST}`)"
- "traefik.http.routers.frontend_iam.tls=true"

indicium_iam:
image: registry.thinkwisesoftware.com/public/indicium:${TAG}
environment:
- SQL_SERVER=${SQL_SERVER}
- SQL_USERNAME=${SQL_USERNAME}
- SQL_PASSWORD=${SQL_PASSWORD}
- SQL_DATABASE=IAM
- ENABLE_REVERSE_PROXY=true
- ALLOWED_HEADERS=All
- TRUSTED_NETWORKS=172.23.0.0/16
- EXTERNAL_PATH_BASE=/indicium
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend_iam.rule=(Host(`${EXTERNAL_HOST}`) && PathPrefix(`/indicium`))"
- "traefik.http.middlewares.backend_iam.stripprefix.prefixes=/indicium"
- "traefik.http.routers.backend_iam.middlewares=backend_iam"
- "traefik.http.routers.backend_iam.tls=true"

indicium_sf:
image: registry.thinkwisesoftware.com/public/indicium:${TAG}
environment:
- SQL_SERVER=${SQL_SERVER}
- SQL_USERNAME=${SQL_USERNAME}
- SQL_PASSWORD=${SQL_PASSWORD}
- SQL_DATABASE=IAM_SF
- ENABLE_REVERSE_PROXY=true
- ALLOWED_HEADERS=All
- TRUSTED_NETWORKS=172.23.0.0/16
- EXTERNAL_PATH_BASE=/indicium_sf
labels:
- "traefik.enable=true"
- "traefik.http.routers.backend_sf.rule=(Host(`${EXTERNAL_HOST}`) && PathPrefix(`/indicium_sf`))"
- "traefik.http.middlewares.backend_sf.stripprefix.prefixes=/indicium_sf"
- "traefik.http.routers.backend_sf.middlewares=backend_sf"
- "traefik.http.routers.backend_sf.tls=true"

Make sure to give the Traefik HTTP routers unique names per defined service in the Compose file.

For example, I use the name `backend_sf` and `backend_iam` for the development and production instances of Indicium.


Hi ​@Leon Kroon ! That was a very helpful response. Yaml syntax for Docker and Traefik is all still very new to me but it’s starting to make sense now. Happy to report I got the extra Indicium instance working.


Reply