hapi-fhir-jpaserver-starter icon indicating copy to clipboard operation
hapi-fhir-jpaserver-starter copied to clipboard

v6.6.0+ Docker images all failing to start in R5 mode

Open preston opened this issue 2 years ago • 33 comments

The "latest" Docker Hub repository tag (as of today), v6.8.0, and v6.6.0 docker images are all failing to start in R5 mode with a Spring runtime exception at startup. It appears to be a missing IEmailSender bean definition. This seems to have been introduced after v6.4.4, as v6.4.4 starts as expected. For example, docker run -it --rm -p 8080:8080 -e hapi.fhir.fhir_version=R5 hapiproject/hapi:latest (and v6.8.0 and v6.6.0) always fail to start with the following runtime exception:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'subscriptionDeliveryHandlerFactory' defined in ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig: Unsatisfied dependency expressed through method 'subscriptionDeliveryHandlerFactory' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
    ... 56 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1396)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
    ... 69 common frames omitted

preston avatar Oct 06 '23 15:10 preston

Also reported via Zulip, here: https://chat.fhir.org/#narrow/stream/179167-hapi/topic/R5.20Docker.20Crashing/near/395149283

preston avatar Oct 06 '23 15:10 preston

Hi @jkiddo, Thank you for working on this! Any chance we could get a new build? I'm happy to test it. :) Unfortunately this bug means that there are no builds supporting R5 final, as 6.4.4 implements 5.0.0-ballot and has some differences. (The *-tomcat builds always starts in R4 mode and seem ignore the hapi.fhir.fhir_version variable.)

preston avatar Oct 11 '23 14:10 preston

I cannot approve it. For that we need some other folks.

jkiddo avatar Oct 11 '23 14:10 jkiddo

Understood.. Who can validate and authorize this? I'd like to politely request a patch release.

preston avatar Oct 11 '23 15:10 preston

I just Approved @jkiddo 's PR now. @preston please confirm that everything looks good to you now, thanks!

KevinDougan avatar Oct 11 '23 15:10 KevinDougan

Thank you @KevinDougan-SmileCDR ! Do the "latest" Docker Hub images get built automatically by CI? ..or is that a separate request?

preston avatar Oct 11 '23 16:10 preston

No ... latest only reflects latest released right now. Also, this patch goes to 6.8.x. @dotasek would you be able to do a patch release if @preston can verify it works for him locally?

jkiddo avatar Oct 11 '23 16:10 jkiddo

@preston you should be able to build it locally only using docker from the Dockerfile in the repo.

jkiddo avatar Oct 11 '23 16:10 jkiddo

@jkiddo release 6.8.1 cut from latest master, correct?

dotasek avatar Oct 11 '23 17:10 dotasek

I definitely could be building it wrong, but on a Ubuntu x64 machine:

docker build -t p3000/hapi-fhir-jpaserver-starter:latest .

docker run -it --rm -p 8080:8080 -e hapi.fhir.fhir_version=R5 p3000/hapi-fhir-jpaserver-starter:latest

Throws the following JDBC-related exception at startup.

Caused by: org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
	at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:71)
	at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:63)
	at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:43)
	at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:39)
	at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:66)
	at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:60)
	at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:183)
	at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:104)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:196)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:85)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
	at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
	... 107 common frames omitted
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: Error while creating file "/app/target" [90062-220]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
	at org.h2.message.DbException.get(DbException.java:212)
	at org.h2.store.fs.disk.FilePathDisk.createDirectory(FilePathDisk.java:391)
	at org.h2.store.fs.FileUtils.createDirectory(FileUtils.java:85)
	at org.h2.store.fs.FileUtils.createDirectories(FileUtils.java:382)
	at org.h2.store.fs.FileUtils.createDirectories(FileUtils.java:381)
	at org.h2.mvstore.db.Store.<init>(Store.java:106)
	at org.h2.engine.Database.<init>(Database.java:324)
	at org.h2.engine.Engine.openSession(Engine.java:92)
	at org.h2.engine.Engine.openSession(Engine.java:222)
	at org.h2.engine.Engine.createSession(Engine.java:201)
	at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
	at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
	at org.h2.Driver.connect(Driver.java:59)
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:359)
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:201)
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:470)
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:100)
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
	at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
	at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
	... 122 common frames omitted
Caused by: java.nio.file.AccessDeniedException: /app/target
	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:90)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
	at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:397)
	at java.base/java.nio.file.Files.createDirectory(Files.java:700)
	at org.h2.store.fs.disk.FilePathDisk.createDirectory(FilePathDisk.java:382)
	... 143 common frames omitted

preston avatar Oct 11 '23 17:10 preston

The Dockerfile creates a /target dir, but not /app/target. Looks like the nonroot user doesn't have permissions to create it. Probably an easy fix, but I'm not sure how it was working previously.

XcrigX avatar Oct 11 '23 17:10 XcrigX

@jkiddo after reflecting on this, I think this should be image/v6.8.0.1, if we're going off the master branch. We're bound to the HAPI parent pom, which is still 6.8.0, so I don't want to create confusion.

dotasek avatar Oct 11 '23 17:10 dotasek

Sure - makes sense

jkiddo avatar Oct 11 '23 17:10 jkiddo

But technically the starter project 'just' consumes the base project so the versioning doesnt have to be aligned - but I follow you

jkiddo avatar Oct 11 '23 17:10 jkiddo

@preston do you have any local modifications to the application.yaml?

jkiddo avatar Oct 11 '23 18:10 jkiddo

@jkiddo Nope. Clean checkout of master. Build and run with the exact commands and throws the runtime exception about /app/target every time. Docker version 24.0.5, build 24.0.5-0ubuntu1~23.04.1

preston avatar Oct 11 '23 18:10 preston

The Dockerfile creates a /target dir, but not /app/target. Looks like the nonroot user doesn't have permissions to create it. Probably an easy fix, but I'm not sure how it was working previously.

@XcrigX where does it create a /target dir in the Dockerfile for the default build? I can see its the case for the tomcat one but not for the distroless (default) variant

jkiddo avatar Oct 11 '23 19:10 jkiddo

@preston can you verify that the rest of it works by running docker run -it --rm -p 8080:8080 -e hapi.fhir.fhir_version=R5 -e spring.datasource.url=jdbc:h2:mem:test_mem p3000/hapi-fhir-jpaserver-starter:latest

jkiddo avatar Oct 11 '23 19:10 jkiddo

The Dockerfile creates a /target dir, but not /app/target. Looks like the nonroot user doesn't have permissions to create it. Probably an easy fix, but I'm not sure how it was working previously.

@XcrigX where does it create a /target dir in the Dockerfile for the default build? I can see its the case for the tomcat one but not for the distroless (default) variant

@jkiddo - I see.. I wasn't looking that closely. Regardless, it seems that directory needs to pre-exist? But I may just be misunderstanding something because again, I'm not clear how it was working previously without that? Perhaps ignore me if I'm not being helpful here. ;)

XcrigX avatar Oct 11 '23 19:10 XcrigX

@XcrigX not at all - you're on to something here, but this part has not been changed for ages. Biggest problem is that I cannot reproduce it locally.

jkiddo avatar Oct 11 '23 20:10 jkiddo

@preston can you verify that the rest of it works by running docker run -it --rm -p 8080:8080 -e hapi.fhir.fhir_version=R5 -e spring.datasource.url=jdbc:h2:mem:test_mem p3000/hapi-fhir-jpaserver-starter:latest

@jkiddo Similar runtime exception having to do with /app/target :

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: HAPI_PU] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:

    index 'TermConcept': 
        failures: 
          - HSEARCH600154: Unable to start index: HSEARCH600015: Unable to initialize index directory: /app/target
            Context: index 'TermConcept'
    index 'ResourceTable': 
        failures: 
          - HSEARCH600154: Unable to start index: HSEARCH600015: Unable to initialize index directory: /app/target
            Context: index 'ResourceTable'
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
	... 103 common frames omitted
Caused by: org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:

    index 'TermConcept': 
        failures: 
          - HSEARCH600154: Unable to start index: HSEARCH600015: Unable to initialize index directory: /app/target
            Context: index 'TermConcept'
    index 'ResourceTable': 
        failures: 
          - HSEARCH600154: Unable to start index: HSEARCH600015: Unable to initialize index directory: /app/target
            Context: index 'ResourceTable'
	at org.hibernate.search.engine.reporting.spi.RootFailureCollector.checkNoFailure(RootFailureCollector.java:53)
	at org.hibernate.search.engine.common.impl.SearchIntegrationPartialBuildStateImpl$SearchIntegrationFinalizerImpl.finalizeIntegration(SearchIntegrationPartialBuildStateImpl.java:188)
	at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationPartialBuildState.doBootSecondPhase(HibernateOrmIntegrationPartialBuildState.java:75)
	at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:176)
	at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
	at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:41)
	at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:402)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
	at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:141)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
	... 107 common frames omitted

preston avatar Oct 11 '23 20:10 preston

FWIW, I get the same error when running @preston 's build/run commands locally. Fresh clone of master - I'm running in a WSL2 (windows) Ubuntu 20.x instance, not that I think it would make any difference.

XcrigX avatar Oct 11 '23 20:10 XcrigX

In lieu of a patch release, I did release jpa-s-s 6.8.3. This was an opportunity to update to HAPI 6.8.3. If another patch release is required, please ping me here, or on zulip.

dotasek avatar Oct 12 '23 20:10 dotasek

Thanks all for working on this! The 6.8.3 release seems to be working now as expected when started in R5 mode.

preston avatar Oct 13 '23 00:10 preston

The CI pipeline builds definitely are not build by a root user, hence it makes sense that the 6.8.3 works. @preston the local build you did - was that done using a regular user i a folder not owned by anyone special?

jkiddo avatar Oct 13 '23 04:10 jkiddo

was that done using a regular user i a folder not owned by anyone special?

@jkiddo Yup .. just a regular Ubuntu user account. Nothing special. I don't think I'm understanding the way the distroless builds work regarding user/group filesystem permissions.

preston avatar Oct 13 '23 18:10 preston

The build environment/builder doesn't matter, does it? All those permissions/directories are within the docker build/container, no?

XcrigX avatar Oct 13 '23 19:10 XcrigX

Yeah - but I cant think of anything else influencing on it

jkiddo avatar Oct 13 '23 20:10 jkiddo

It might be something related to the way different builder and runtime implementations are configured to map permissions to a host systems both at build time and run time, which is somewhat configurable per installation. I'm guessing everyone here is using Docker Desktop for local use, but I recall having issues with other projects in the past with images assuming root vs non-root permissions at runtime.

@dotasek What CI system and builder builds these? They are multiarch (thank you for supporting that too btw) and we are also using the ARM64 images.

preston avatar Oct 13 '23 20:10 preston

@preston I believe these are all built via this GitHub action: https://github.com/hapifhir/hapi-fhir-jpaserver-starter/blob/master/.github/workflows/build-images.yaml

This is my first time taking a look at that file, so this is just an educated guess based on the action trigger and the tagging I performed for the last two releases.

They'll run on whatever ubuntu-20.04 GitHub runners are available. Any info regarding the docker steps and permissions is likely in buried in GitHub actions documentation.

dotasek avatar Oct 13 '23 21:10 dotasek