Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X
Hi all, I've been trying to get the Twx 9.5.0 dockerfiles up and running on WSL2. I've managed to build all of my images (Security CLI, platform-postgres) and get them to spin, but it looks like Thingworx can't connect to the provided 'starter postgres' database, and the Platform shuts down:
2024-05-02 21:04:35.758+0000 [L: ERROR] [O: c.t.s.ThingWorxBootstrapper] [I: ] [U: SuperUser] [S: ] [P: ] [T: main] *** CRITICAL ERROR ON STARTUP: Connections could not be acquired from the underlying database!
2024-05-02 21:04:35.758+0000 [L: ERROR] [O: c.t.s.ThingWorxBootstrapper] [I: ] [U: SuperUser] [S: ] [P: ] [T: main] *** Web Application STATE is being set to ERROR! ***
2024-05-02 21:04:35.758+0000 [L: INFO] [O: c.t.s.ThingWorxServer] [I: ] [U: SuperUser] [S: ] [P: ] [T: main] >>>>>>> PLATFORM SHUTDOWN START <<<<<<<<<
I've handled this error for non-Docker installs. But this database is ephemeral, I think I've searched myself in circles, and I'm not sure how to further debug. From what I can tell, my Compose file should be fine (below). Have I misconfigured something, forgotten to open some port on Windows, or am I missing something? Any wisdom would be appreciated.
version: '2.2'
volumes:
storage:
services:
postgresql:
image: postgres:15.4
ports:
- "5432"
healthcheck:
test: pg_isready -U postgres
interval: 15s
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
- "POSTGRES_DB=postgres"
postgresql-init:
image: thingworx/postgresql-init-twx:latest
entrypoint: bash -c -x "/usr/local/bin/db-check.sh && /usr/local/bin/db-setup.sh && sleep infinity"
healthcheck:
test: [ "CMD-SHELL", "grep 'success' tmp/status.txt || exit 1" ]
interval: 15s
retries: 5
depends_on:
postgresql:
condition: service_healthy
environment:
- "DATABASE_ADMIN_USERNAME=postgres"
- "DATABASE_ADMIN_PASSWORD=postgres"
- "DATABASE_ADMIN_SCHEMA=postgres"
- "DATABASE_HOST=postgresql"
- "DATABASE_PORT=5432"
- "TWX_DATABASE_USERNAME=twadmin"
- "TWX_DATABASE_SCHEMA=twadmin"
- "TWX_DATABASE_PASSWORD=Redacted"
- "TABLESPACE_LOCATION=/var/lib/postgresql/data"
security-cli:
image: thingworx/security-tool:latest
entrypoint: sh -c "/opt/docker-entrypoint.sh && sleep infinity"
healthcheck:
test: [ "CMD-SHELL", "grep 'success' status.txt || exit 1" ]
interval: 15s
retries: 5
environment:
KEYSTORE: 'true'
KEYSTORE_PASSWORD: 'Redacted'
KEYSTORE_PASSWORD_FILE_PATH: '/opt'
KEYSTORE_FILE_PATH: '/ThingworxStorage'
CUSTOM_SECRET_LIST: 'encrypt.db.password:TWX_DATABASE_PASSWORD'
TWX_DATABASE_PASSWORD: 'Redacted'
SECRET_PROVISIONING_APP_KEY: 'VerySecret'
volumes:
- storage:/ThingworxStorage
platform:
image: thingworx/platform-postgres:latest
healthcheck:
test: curl -f localhost:8080/Thingworx/health
interval: 15s
depends_on:
security-cli:
condition: service_healthy
postgresql-init:
condition: service_healthy
ports:
- "8080:8080"
- "8443:8443"
environment:
- "CATALINA_OPTS=-Xms2g -Xmx4g"
- "KEYSTORE_PASSWORD=Redacted"
- "SECRET_PROVISIONING_APP_KEY=VerySecret"
- "DATABASE_HOST=postgresql"
- "DATABASE_PORT=5432"
- "TWX_DATABASE_USERNAME=twadmin"
- "TWX_DATABASE_SCHEMA=twadmin"
- "THINGWORX_INITIAL_ADMIN_PASSWORD=MinimumRequirements"
- "THINGWORX_INITIAL_METRICS_USER_PASSWORD="
#Uncomment the below to automatically download license
#- "LS_USERNAME=${PTCUSERNAME}"
#- "LS_PASSWORD=${PTCPASSWORD}"
# Use this to mount your orgs licence file, if not ThingWorx will fallback to temporary licence
volumes:
# - storage:/ThingworxStorage
- "./thingworx-storage/shared/ThingworxPlatform:/ThingworxPlatform"
- "./thingworx-storage/platform1/ThingworxStorage:/ThingworxStorage"
- "./thingworx-storage/platform1/ThingworxBackupStorage:/ThingworxBackupStorage"
- "./thingworx-storage/platform1/tomcat-logs:/app/opt/apache-tomcat/logs"
# - ./license.bin:/ThingworxPlatform/license.bin
Hello @AM_9930586 , You are using the WSL2 to run a Docker container. Is there a reason for this configuration?
When I look at the yml file which you have included. Why is there no "volumes:" section for the postgresql section?
In my test environment I have:
In your Security-CLI you are storing inforamtion in the default location. You might want to assign that to a specific location:
You have not provided a value for "THINGWORX_INITIAL_METRICS_USER_PASSWORD" not having a value for this symbol will result in an error message.
For the field "SECRET_PROVISIONING_APP_KEY=VerySecret" If VerySecret is redacted GUID, great. If not then you need to get a GUID value.
you have directed storage of log to directories.
- "./thingworx-storage/shared/ThingworxPlatform:/ThingworxPlatform"
- "./thingworx-storage/platform1/ThingworxStorage:/ThingworxStorage"
- "./thingworx-storage/platform1/ThingworxBackupStorage:/ThingworxBackupStorage"
- "./thingworx-storage/platform1/tomcat-logs:/app/opt/apache-tomcat/logs"
have you reviewed the log files? /ThingworxStorage/logs/...., /app/opt/apache-tomcat/logs
If ThingWorx/Tomcat is starting there will be information in the logs which identify why?
HTH
Peter
I run Docker under WSL2 because I wish to avoid using the Docker Desktop software product, and because it gives me a Linux-like environment. Last I tried anything 'Docker for Windows', it was a huge pain. I was able to do my Docker CLI tutorials on WSL2, so it works as a host environment.
I'm not running this as any kind of Production server, but am working to get it running in the default state before I tweak too much of it. So, in regard to data in default locations, it should be fine. When I generated this file, there was no 'Volumes' section in the Postgres service, so I didn't touch it. I don't need to save any of the data from this container, and will move to using an external DB in later steps.
I've also made some changes to my config based on your reply. Metrics user has a password set, and I updated the Secret Provisioning key (formerly, it was a non-GUID string), but I get the same issues (Critical Error On Startup, Connections could not be acquired from underlying DB). Does your own Secret App Key GUID use the same format as I show? I used https://www.guidgenerator.com/ to make something up.
And yes, I've read into the Thingworx logs. I have to chmod them every time I run the containers, but they show what I would describe as "Thingworx turns on, can't connect to the DB, and shuts down." All the other containers seem to be doing fine.
Replying to myself as I keep working this:
I've managed to inspect the provided Postgres DB with pgadmin, by mapping an external port and just logging in. I can verify that the 'init' ran on the DB, since Thingworx-looking tables appeared under my Thingworx DB user's schema.
Running 'docker inspect' on the Platform container, I can see passwords are set correctly:
Still not sure why Platform can't reach Postgres, but still trying to find out.
Thanks for keeping this updated, it will provide learnings to others. I think you're close!
Probably can't help a lot, but taking this apart, you know now the db tables were created properly. Thingworx is coming up and tries to connect, but it can't. Now you can work through those points:
-Does TWX Container use right DB Connection string/ServerName/Database/Schema/User/Password? (your posting indicates this seems to be correct)
-Does DB allow access from another container? Check pg_hba.conf and this
-Is TWX Container allowed to see/access DB Container? Check Docker network configs
I made an explicit Bridge-type network, and connected all of the Services to it. That alone didn't help, so I re-tread my previous steps. I had no luck for the longest time, but found a temporary solution, by setting `POSTGRES_HOST_AUTH_METHOD=trust`. It's laughable for security reasons, but works for now, posted below.
Given this, does anyone have ideas on how to reconfigure with proper security? I still don't understand how the 'init' container connected, while the 'platform' was (previously) unable.
version: '2.2'
volumes:
storage:
networks:
dockerNet:
driver: bridge
services:
postgresql:
image: postgres:15.4
ports:
- "15432:5432"
healthcheck:
test: pg_isready -U postgres
interval: 15s
environment:
- "POSTGRES_USER=postgres"
- "POSTGRES_PASSWORD=postgres"
- "POSTGRES_DB=postgres"
- "TWX_DATABASE_USERNAME=thingworx"
- "TWX_DATABASE_SCHEMA=thingworx"
- "TWX_DATABASE_PASSWORD=RedHerring42"
- "POSTGRES_HOST_AUTH_METHOD=trust"
volumes:
#- "./thingworx-storage/postgres/data:/var/lib/postgresql/data"
- storage:/var/lib/postgresql/data
networks:
dockerNet:
aliases:
- pgserv
postgresql-init:
image: thingworx/postgresql-init-twx:latest
entrypoint: bash -c -x "/usr/local/bin/db-check.sh && /usr/local/bin/db-setup.sh && sleep infinity"
healthcheck:
test: [ "CMD-SHELL", "grep 'success' tmp/status.txt || exit 1" ]
interval: 15s
retries: 5
depends_on:
postgresql:
condition: service_healthy
environment:
- "DATABASE_ADMIN_USERNAME=postgres"
- "DATABASE_ADMIN_PASSWORD=postgres"
- "DATABASE_ADMIN_SCHEMA=postgres"
- "DATABASE_HOST=pgserv"
- "DATABASE_PORT=5432"
- "TWX_DATABASE_USERNAME=thingworx"
- "TWX_DATABASE_SCHEMA=thingworx"
- "TWX_DATABASE_PASSWORD=RedHerring42"
- "TABLESPACE_LOCATION=/var/lib/postgresql/data"
networks:
dockerNet:
aliases:
- pginit
security-cli:
image: thingworx/security-tool:latest
entrypoint: sh -c "/opt/docker-entrypoint.sh && sleep infinity"
healthcheck:
test: [ "CMD-SHELL", "grep 'success' status.txt || exit 1" ]
interval: 15s
retries: 5
environment:
KEYSTORE: 'true'
KEYSTORE_PASSWORD: 'RedHerring42'
KEYSTORE_PASSWORD_FILE_PATH: '/opt'
KEYSTORE_FILE_PATH: '/ThingworxStorage'
CUSTOM_SECRET_LIST: 'encrypt.db.password:TWX_DATABASE_PASSWORD'
TWX_DATABASE_PASSWORD: 'RedHerring42'
SECRET_PROVISIONING_APP_KEY: '9605cf44-0b66-40ba-8cad-d5de56b0bcb7'
volumes:
- "./thingworx-storage/SecurityCLI:/ThingworxStorage"
networks:
dockerNet:
aliases:
- securityCLI
platform:
image: thingworx/platform-postgres:latest
healthcheck:
test: curl -f localhost:8080/Thingworx/health
interval: 15s
depends_on:
security-cli:
condition: service_healthy
postgresql-init:
condition: service_healthy
ports:
- "8080:8080"
- "8443:8443"
environment:
- "CATALINA_OPTS=-Xms2g -Xmx4g"
- "KEYSTORE_PASSWORD=RedHerring42"
- "SECRET_PROVISIONING_APP_KEY=9605cf44-0b66-40ba-8cad-d5de56b0bcb7"
- "DATABASE_HOST=pgserv"
- "DATABASE_PORT=5432"
- "TWX_DATABASE_USERNAME=thingworx"
- "TWX_DATABASE_SCHEMA=thingworx"
- "TWX_DATABASE_PASSWORD=RedHerring42"
- "DOCKER_DEBUG=true"
- "TABLESPACE_LOCATION=/var/lib/postgresql/data"
- "THINGWORX_INITIAL_ADMIN_PASSWORD=MinimumRequirements"
- "THINGWORX_INITIAL_METRICS_USER_PASSWORD=MinimumRequirements"
#Uncomment the below to automatically download license
#- "LS_USERNAME=${PTCUSERNAME}"
#- "LS_PASSWORD=${PTCPASSWORD}"
# Use this to mount your orgs licence file, if not ThingWorx will fallback to temporary licence
volumes:
# - storage:/ThingworxStorage
- "./thingworx-storage/shared/ThingworxPlatform:/ThingworxPlatform"
- "./thingworx-storage/platform1/ThingworxStorage:/ThingworxStorage"
# - "./thingworx-storage/platform1/ThingworxBackupStorage:/ThingworxBackupStorage"
- "./thingworx-storage/platform1/tomcat-logs:/app/opt/apache-tomcat/logs"
# - ./license.bin:/ThingworxPlatform/license.bin
networks:
dockerNet:
aliases:
- platform