Not able to run app using docker

Hi, I am using the instructions from Mario David to run the application using docker: https://www.road-to-cuba-and-beyond.com/put-a-island-into-a-box-how-to-dockerize-your-cuba-app/.
I managed to work through fine an also created war files and extended the local.app.properties files in both war files to hold the proper server reference as instructed here: https://doc.cuba-platform.com/manual-6.3/tomcat_in_prod.html

The server (Ubuntu 16.04) is able to ping the public server name, firewall is turned off.

After starting the application the startup seems to do fine as well (there is an error but it seems to be related to multiple startups in which a table is to be created which already exists: ERROR: relation “sys_db_changelog” already exists).

When accessing the app through the browser I do get an initial response but then it fails (browser: unexpected error), logging:


Invocation of http://<server>:8080/app-core/remoting/cuba_LoginService failed: java.io.IOException: Did not receive successful HTTP response: status code = 404, status message = [Not Found]

( replaces the actual server name)

Logging of the docker images is attached which shows the full error.

I am not sure if you are willing and able to provide support on this but any help is appreciated.

logging.zip (6.8K)

Hi,

did you put your war’s in a single docker container? Or do you use the single war approach?

From the logs it seems that the core-war didn’t start up due to the already described error:


ERROR:  relation "sys_db_changelog" already exists

This results in that the frontend is not able to login against the backend war, since it is just down :slight_smile:

I had seen this “sys_db_changelog” error happen from time to time, but i have no clear answer to this. You can try:


docker kill dockerimage_postgres_1
docker rm dockerimage_postgres_1
docker kill dockerimage_web_1
docker rm dockerimage_web_1

to clear everything up and to make sure that the DB is really empty. If with the next start (docker-compose up) it does not come up, there’s a problem with the database generation scripts i’d guess.

Bye
Mario

I might be wrong, but from your logs it seems that the application is trying to connect to hsql and not postgres.

ee[33mweb_1 | e[0m21:45:39.950 INFO c.h.cuba.core.sys.AppContextLoader - DbmsType of the main database is set to hsql

Hi Mario, Torben,

Your both right; I was under the assumption that the application would pickup the configuration from the context.xml in the docker image. And I think it does but it is unable to execute the proper db scripts as it is still assuming the hsql configuration.

From the documentation (https://doc.cuba-platform.com/manual-6.3/dbms_types.html) I understand that the dbms type needs to be set. So I did in the app.properties which was previously set to hsql, now to postgres. After rebuilding the war files and modifying the local.app.properties in both, I had good hopes that it would run this time but actually, the errors remain the same (although after destroying the previous images as David suggested, the initial error is a bit different ).

This is the app.properties file:


###############################################################################
#                              Configuration                                  #
###############################################################################

cuba.dbmsType = hsql

cuba.springContextConfig = +com/axxemble/base27/spring.xml

cuba.persistenceConfig = +com/axxemble/base27/persistence.xml

cuba.metadataConfig = +com/axxemble/base27/metadata.xml

cuba.viewsConfig = +com/axxemble/base27/views.xml

cuba.mainMessagePack = +com.axxemble.base27.core

cuba.keyForSecurityTokenEncryption = wOTxe6KtM7JmuvPF

cuba.anonymousSessionId = c2424374-6145-2129-87f0-5247d2028bcb

###############################################################################
#                                  Other                                      #
###############################################################################

cuba.webContextName = app-core
cuba.availableLocales = English|en;Nederlands|nl
cuba.localeSelectVisible = true
cuba.ftsConfig = +com/axxemble/base27/fts.xml

This is the local.app.properties file (from the app-core.war):


cuba.logDir = app_home/logs
cuba.confDir = app_home/${cuba.webContextName}/conf
cuba.tempDir = app_home/${cuba.webContextName}/temp
cuba.dataDir = app_home/${cuba.webContextName}/work
cuba.dataSourceJndiName = jdbc/CubaDS
cuba.download.directories = ${cuba.tempDir};${cuba.logDir}
cuba.dbDir = web-inf:db
cuba.automaticDatabaseUpdate = true
cuba.webHostName = xwiki.axxemble.com
cuba.webAppUrl = http://xwiki.axxemble.com:8080/app

And the new logging is attached as well. Any help appreciated.

logging.zip (7.8K)

The app.properties file still mentions hsql (which is my local studio configuration). It was replaced to postgres on building the war files - sorry.

Thanks Mario. I’m a bit further in understanding what is going wrong but my problem is not solved yet (see other comment)

Hi Torben, this is exactly right I think but I am not able to switch the configuration to progres it seems. After modifying the app.properties it doesn’t do anything.

But I also saw there are multiple app.properties files in the project. Do you need to change them all?

Now got my studio setup to use postgres and it works ok - on postgress that is. When then building a war file, there still is an error:


 10:51:33.200 INFO  c.h.c.c.sys.dbupdate.DbUpdaterEngine - Executing script 10-cuba/init/hsql/create-db.sql
postgres_1 | ERROR:  type "longvarchar" does not exist at character 350

So it still is using hsql scripts on creating the database. Not sure why it is doing that as everything I know of is pointing to use postgres…

Try to find out what app properties are actually take effect. Look at web.xml of the WAR file and find the appPropertiesConfig context parameter. It contains all resources that are scanned for properties. Each subsequent resource overrides values set by a previous one. So you can track down what value is actually assigned to cuba.dbmsType.

I also used Mario’s Docker instructions, but modified the dockerfile a bit. Here is my context.xml and dockerfile.


<Context>
    <!-- Database connection -->
    <Resource driverClassName="org.postgresql.Driver"
              maxActive="20"
              maxIdle="2"
              maxWait="5000"
              name="jdbc/CubaDS"
              username="${postgres.user}"
              password="${postgres.pw}"
              type="javax.sql.DataSource"
              url="jdbc:postgresql://${postgres.container}:${postgres.port}/${postgres.db}"
              ></Resource>
    
    <Manager pathname=""></Manager>
</Context>
properties
### Dockerfile

# Base Image: official tomcat 8 image, with jre 8 underneath
FROM tomcat:8-jre8

# Microsoft fonts
RUN echo "deb http://httpredir.debian.org/debian jessie contrib" >> /etc/apt/sources.list
RUN set -x \
	&& apt-get update \
	&& apt-get install -yq ttf-mscorefonts-installer \
	&& rm -rf /var/lib/apt/lists/*

# Add tomcat users file for manager app
ADD container-files/tomcat-users.xml /usr/local/tomcat/conf/

# Add generated app war files to the webapps directory
ADD war/app.war /usr/local/tomcat/webapps/
ADD war/app-core.war /usr/local/tomcat/webapps/
ADD war/app-portal.war /usr/local/tomcat/webapps/

# Add context config file for the application
ADD container-files/context.xml /usr/local/tomcat/conf/

# copy logback.xml config in the container
ADD container-files/logback.xml /opt/cuba_home/

# copy index.jsp so that we get an automatic redirect
ADD container-files/index.jsp /usr/local/tomcat/webapps/ROOT/index.jsp

# set env variables to use from docker container
ENV POSTGRES_CONTAINER=$POSTGRES_CONTAINER
ENV POSTGRES_USER=$POSTGRES_USER
ENV POSTGRES_PW=$POSTGRES_PW
ENV POSTGRES_PORT=$POSTGRES_PORT
ENV POSTGRES_DB=$POSTGRES_DB

# set CATALINA_OPTS env variable to point to logback config file and app home directory
# here the POSTGRES settings are being mapped to java properties
ENV CATALINA_OPTS "-Dlogback.configurationFile=/opt/cuba_home/logback.xml -Dapp.home=/opt/cuba_home -Dpostgres.container=\$POSTGRES_CONTAINER -Dpostgres.user=\$POSTGRES_USER -Dpostgres.pw=\$POSTGRES_PW -Dpostgres.db=\$POSTGRES_DB -Dpostgres.port=\$POSTGRES_PORT"

Hi Torben, thanks - I have gotten a bit further but not there yet.

First of all I had to add the postgres driver to Tomcat as well (as was in the original file from David) then I needed to really put meaningful values into the postgres env variables. They were not set automatically. Should it or did I misunderstood the suggestion here?

Anyway, after hard coding the proper values in there I got at the point where the app-core is actually making a connection to the postgres server only to fail immediately after stating the required database was not found:


Caused by: java.sql.SQLException: Cannot create PoolableConnectionFactory (FATAL: database "base" does not exist)

I thought that to be logical and something that would trigger the creation of the database by app-core. But it did not, it failed and all execution stopped with a ‘SEVERE’ at the very end of it.

BTW: the database name is called ‘base’.

Attached is the full log of this run. Can you explain why it all stops instead of creating the database?

logging.zip (3.4K)

Hi Konstantin,

The web.xml file states:


classpath:cuba-app.properties classpath:com/axxemble/base27/app.properties /WEB-INF/local.app.properties "file:${catalina.home}/conf/app-core/local.app.properties"

I have checked them all but could only find the local.app.properties to exist. Anyway, that one was configured fine and a connection to postgres seems to be working now (see comments in the thread with Torben). But it isn’t working as the app-core is not creating the database - instead, everything stops after there is an exception that the database does not exist (on the first run).

Any ideas what might be wrong?

Copy to clipboardI thought that to be logical and something that would trigger the creation of the database by app-core.

Did you create an empty database named “base”? App core does not actually create a database, it can only create tables in it (unlike createDb Gradle task). This is because usually the app server has no DB superuser permission.

Sorry if I missed something from your previous discussion.

Hi Konstantin, thanks for your help. I did not create the database. That’s mainly because the instructions from David didn’t either and from studio its created automatically as well. Although I now understand this is not always the case.

Puzzles me why there is now mentioning of it in other posts. And it is not something straightforward to do as the postgres docker image is used ‘as is’. I now have to build an image with an empty database it seems.

I will give it a try but some explanation why David and Torben are not mentioning it, or actually seem to do without, would be appreciated.

Hi,

The postgress docker image will create a default database, if no database is specified. This can be seen from the documentation here: https://hub.docker.com/_/postgres/

You can define your own database name using the environment variables. You do not need to create the database manually.

It is then important that your jdbc url actually matches the postgres database name. If not, then you will not be able to connect the database.

If you use my docker file, then the environment variables are easy to match against the postgres ones.

Thanks Torben, this explains why you don’t do anything special on that part. But I’m not sure if I understand the part about the environment variables:

“If you use my docker file, then the environment variables are easy to match against the postgres ones.”

I do see the construction in the Dockerfile but they didn’t work for me. Do I need to set the environment variables in my bash before starting anything? I now just hard coded the correct values in there (rather than using environment variables).

How do I get the progres image to use the correct values?

When you start each docker instance, then you are able to pass values to the environment variables. This is also explained here http://stackoverflow.com/questions/30494050/how-to-pass-environment-variables-to-docker-containers, and even with postgres as an example - although they do not mount a local path to the database, which I believe is important.

You really need to use the environment variables and also make sure that you mount the location of the database to a local path, as you would otherwise loose you data, next time you start the docker postgres instance.

If you are on Mac or Windows, I would really suggest to take a look at Kitematic, which is available in the Docker ToolBox.

Kitematic makes it dead simple to start docker instances and also pass environment variables and mount a local path for an image.

I run my postgres development instance using Kitematic.

Hi,

the reason i didn’t mention it is, that i didn’t use a custom database name in the example.
In the example i used the docker-compose.yml file to create a postgres db. The default docker images of postgres creates a database with the name “postgres” which i reuse.

in the context.xml i used hard coded connection information because i knew that this will run in a docker network wih dns enabled so that i could create a connection to the hostname “postgres”. When you want to externalize the information about the connection you can look at another blog post, which deals with this issue.

Bye,
Mario

Hi Torben, got it working by explicitly setting the env variables on the postgres image through the docker-compose.yml file. I have set them on the Tomcat image earlier on but based on your comments they need to be on there as well.

So, that’s good news.

Next, on first startup every worked well and I was really happy. Then I restarted the docker-images to see if the data was properly persistent only to find out that the tomcat image is not starting up anymore. It seems the app-core starts correctly, but the app itself does not (there is no logging of it). But it also seems Tomcat itself is hanging as I cannot access the root nor /manage/html. No response whatsoever.

But no error either.

Again, attached is the logfile of the restart. Thanks for all your help!

logging.zip (2.7K)