Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 7, 2026

  • Create Dockerfile with multi-stage build (build stage + runtime stage)
  • Create docker-compose.yml for easy orchestration with PostgreSQL
  • Configure volume mounting for JSP files to enable local editing
  • Add .dockerignore file to optimize build context
  • Create example environment configuration files for Docker
  • Add .env.example for customizable environment variables
  • Add documentation on how to use the Docker setup
  • Add validation script for Docker setup
  • Update documentation to use modern docker compose syntax
  • Add quick-start script for easy launch
  • Add comprehensive testing guide
  • Add implementation summary documentation
  • Validate Docker configuration files
  • Address all code review feedback
  • Improve error handling in scripts
  • Remove deprecated docker-compose version field
  • Update .gitignore to exclude .env file
  • Fix PostgreSQL role error - create postgres role for schema compatibility
  • Fix PostgreSQL treebase_app role error - create treebase_app role
  • Fix Tomcat XML parsing error - remove duplicate autoDeploy attribute
  • Add Java 17 compatibility flags from GitHub Actions workflow
  • Fix duplicate CREATE INDEX in SQL schema (matrixelement_discretecharstate_id_idx)
  • Fix volume mount conflict - mount webapp subdirectories individually to preserve WEB-INF
  • Complete implementation with 16 files, ~2,000 lines of code and documentation
Original prompt

Write a Dockerfile that deploys the web application. What I need is a solution that makes it easy for me to edit JSP files locally in the checked out source tree so that I can quickly iterate on the look of the UI.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 6 commits January 7, 2026 20:05
Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
…d version field

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Dockerfile for deploying web application Add Docker deployment with JSP hot-reload for rapid UI development Jan 7, 2026
Copilot AI requested a review from rvosa January 7, 2026 20:19
@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot I ran ./docker/quick-start.sh but there was a problem:

treebase-postgres  | /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/01-schema.sql
treebase-postgres  | CREATE TABLE
treebase-postgres  | 2026-01-07 20:40:37.305 UTC [61] ERROR:  role "postgres" does not exist
treebase-postgres  | 2026-01-07 20:40:37.305 UTC [61] STATEMENT:  ALTER TABLE algorithm OWNER TO postgres;
treebase-postgres  | psql:/docker-entrypoint-initdb.d/01-schema.sql:14: ERROR:  role "postgres" does not exist

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot I ran ./docker/quick-start.sh but there was a problem:

...

Fixed in commit 67ff958. The schema SQL file (TBASE2_POSTGRES_CREATION.sql) contains ALTER TABLE ... OWNER TO postgres; statements (98 total), but the Docker setup uses treebase as the database user.

Added docker/00-init-roles.sql that runs before schema initialization to:

  • Create the postgres role if it doesn't exist
  • Grant the role to the treebase user

This allows the schema to load successfully while maintaining the treebase user for application access. The validation and quick-start scripts now check for this file.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot there was a problem launching Tomcat. Make sure you are not reinventing the wheel - if need be, consult the GitHub Action YAML file to understand how a working Tomcat can be launched for this web app. This was the error I saw:


		at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)

		at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)

		at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)

		at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)

		at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)

		at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)

		at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)

		at org.apache.catalina.startup.Catalina.load(Catalina.java:672)

		at org.apache.catalina.startup.Catalina.load(Catalina.java:710)

		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)

		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

		at java.base/java.lang.reflect.Method.invoke(Method.java:569)

		at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)

		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)

07-Jan-2026 20:47:48.783 WARNING [main] org.apache.catalina.startup.Catalina.parseServerXml Unable to load server configuration from [/usr/local/tomcat/conf/server.xml]

	org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 164; columnNumber: 48; Attribute "autoDeploy" was already specified for element "Host".

		at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1251)

		at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)

		at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)

		at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)

		at org.apache.catalina.startup.Catalina.load(Catalina.java:672)

		at org.apache.catalina.startup.Catalina.load(Catalina.java:710)

		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)

		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

		at java.base/java.lang.reflect.Method.invoke(Method.java:569)

		at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)

		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)

07-Jan-2026 20:47:48.783 SEVERE [main] org.apache.catalina.startup.Catalina.start Cannot start server, server instance is not configured


@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot Sorry, here is the full trace:

treebase-web-dev   | NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
treebase-web-dev   | 07-Jan-2026 20:47:48.782 SEVERE [main] org.apache.tomcat.util.digester.Digester.fatalError Parse fatal error at line [164] column [48]
treebase-web-dev   |    org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 164; columnNumber: 48; Attribute "autoDeploy" was already specified for element "Host".
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1465)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(XMLDocumentFragmentScannerImpl.java:1534)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1363)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2726)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
treebase-web-dev   |            at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:672)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:710)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
treebase-web-dev   |            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |            at java.base/java.lang.reflect.Method.invoke(Method.java:569)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)
treebase-web-dev   | 07-Jan-2026 20:47:48.783 WARNING [main] org.apache.catalina.startup.Catalina.parseServerXml Unable to load server configuration from [/usr/local/tomcat/conf/server.xml]
treebase-web-dev   |    org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 164; columnNumber: 48; Attribute "autoDeploy" was already specified for element "Host".
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1251)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
treebase-web-dev   |            at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:672)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:710)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
treebase-web-dev   |            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |            at java.base/java.lang.reflect.Method.invoke(Method.java:569)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)
treebase-web-dev   | 07-Jan-2026 20:47:48.783 SEVERE [main] org.apache.catalina.startup.Catalina.start Cannot start server, server instance is not configured
treebase-web-dev exited with code 1


…tibility flags

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot there was a problem launching Tomcat. Make sure you are not reinventing the wheel - if need be, consult the GitHub Action YAML file to understand how a working Tomcat can be launched for this...

Fixed in commit 498aa00. The issue was caused by trying to add a duplicate autoDeploy="true" attribute to Tomcat's server.xml - the default configuration already has this attribute.

Changes made based on the GitHub Actions workflow:

  1. Removed the problematic sed command that was modifying server.xml
  2. Added Java 17 compatibility flags (--add-opens) to CATALINA_OPTS in both Dockerfiles
  3. Added comment noting that default Tomcat config already has autoDeploy="true"

The Dockerfiles now use the same JVM flags as the working GitHub Actions deployment.

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot Sorry, here is the full trace:

...

This error was already fixed in commit 498aa00, but you're seeing it because Docker is using a cached image built before the fix.

To pick up the changes, rebuild the Docker image:

# Stop and remove containers and volumes
docker compose down -v

# Rebuild the image (force no cache)
docker compose --profile development build --no-cache

# Start fresh
docker compose --profile development up

The --no-cache flag ensures Docker rebuilds from scratch and doesn't use the old image with the problematic sed command.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot still happening:

treebase-web-dev   | NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
treebase-web-dev   | 07-Jan-2026 20:57:36.200 SEVERE [main] org.apache.tomcat.util.digester.Digester.fatalError Parse fatal error at line [164] column [48]
treebase-web-dev   |    org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 164; columnNumber: 48; Attribute "autoDeploy" was already specified for element "Host".
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:204)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:178)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1465)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanAttribute(XMLDocumentFragmentScannerImpl.java:1534)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1363)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2726)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1224)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
treebase-web-dev   |            at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:672)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:710)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
treebase-web-dev   |            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |            at java.base/java.lang.reflect.Method.invoke(Method.java:569)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)
treebase-web-dev   | 07-Jan-2026 20:57:36.201 WARNING [main] org.apache.catalina.startup.Catalina.parseServerXml Unable to load server configuration from [/usr/local/tomcat/conf/server.xml]
treebase-web-dev   |    org.xml.sax.SAXParseException; systemId: file:/usr/local/tomcat/conf/server.xml; lineNumber: 164; columnNumber: 48; Attribute "autoDeploy" was already specified for element "Host".
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1251)
treebase-web-dev   |            at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:637)
treebase-web-dev   |            at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:580)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:672)
treebase-web-dev   |            at org.apache.catalina.startup.Catalina.load(Catalina.java:710)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
treebase-web-dev   |            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
treebase-web-dev   |            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
treebase-web-dev   |            at java.base/java.lang.reflect.Method.invoke(Method.java:569)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:299)
treebase-web-dev   |            at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:472)
treebase-web-dev   | 07-Jan-2026 20:57:36.202 SEVERE [main] org.apache.catalina.startup.Catalina.start Cannot start server, server instance is not configured
treebase-web-dev exited with code 1

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot still happening:

...

You need to pull the latest code from the PR branch. The fix in commit 498aa00 is in the repository but your local copy appears to be outdated.

Run these commands to get the fix:

# Ensure you have the latest code
git fetch origin
git checkout copilot/add-dockerfile-for-web-app
git pull origin copilot/add-dockerfile-for-web-app

# Verify the fix is present (should see NO sed command)
grep -n "sed" Dockerfile.dev

# Clean up old Docker artifacts
docker compose down -v
docker system prune -af

# Rebuild from scratch
docker compose --profile development build --no-cache

# Start
docker compose --profile development up

The grep command should return only a comment about autoDeploy, not an actual sed command. If you see a RUN sed line, you don't have the latest code.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot tomcat launches but I get a 404 and the following error:

treebase-web-dev   | 07-Jan-2026 21:12:29.749 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file
treebase-web-dev   | 07-Jan-2026 21:12:29.756 SEVERE [main] org.apache.catalina.core.StandardContext.startInternal Context [/treebase-web] startup failed due to previous errors

What do I need to check?

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot tomcat launches but I get a 404 and the following error:

...

The "listeners failed to start" error typically indicates missing dependencies or configuration issues. Check the following:

  1. View the full Tomcat logs for the root cause:
docker compose logs web-dev | grep -A 20 "SEVERE"
  1. Common issues to look for:

    • Missing DTD files (validator configuration)
    • Database connection failures
    • Missing JAR dependencies in WEB-INF/lib
    • Spring context initialization errors
  2. Check if WEB-INF was properly extracted:

docker exec -it treebase-web-dev ls -la /usr/local/tomcat/webapps/treebase-web/WEB-INF/
  1. Verify the build completed successfully:
docker compose logs web-dev | grep "BUILD SUCCESS"

The full log output will show which specific listener failed and why. Share the complete error trace from the logs (not just the SEVERE lines) and I can help diagnose the specific issue.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot docker compose logs web-dev | grep -A 20 "SEVERE" just gives the same catalina.out. We need to see the localhost.*.log for the full traces but I don't know how to access that.

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot docker compose logs web-dev | grep -A 20 "SEVERE" just gives the same catalina.out. We need to see the localhost.*.log for the full traces but I don't know how to access that.

To access the localhost log files, use these commands:

# List all log files in the container
docker exec -it treebase-web-dev ls -la /usr/local/tomcat/logs/

# View the localhost log (replace the date with actual file)
docker exec -it treebase-web-dev cat /usr/local/tomcat/logs/localhost.$(date +%Y-%m-%d).log

# Or tail it to see recent entries
docker exec -it treebase-web-dev tail -100 /usr/local/tomcat/logs/localhost.$(date +%Y-%m-%d).log

# View all logs at once
docker exec -it treebase-web-dev sh -c "cat /usr/local/tomcat/logs/*.log"

Alternatively, copy the log files to your host:

docker cp treebase-web-dev:/usr/local/tomcat/logs/ ./tomcat-logs/
ls -la ./tomcat-logs/
cat ./tomcat-logs/localhost.*.log

Share the output and I can identify the specific initialization failure.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot from localhost.*.log:

07-Jan-2026 21:12:29.748 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [net.bull.javamelody.SessionListener]
	java.lang.ClassNotFoundException: net.bull.javamelody.SessionListener
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1351)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1160)
		at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:484)
		at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:466)
		at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3974)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4489)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:597)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:569)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:608)
		at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677)
		at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1836)
		at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
		at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:572)
		at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:463)
		at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)
		at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
		at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109)
		at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389)
		at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:774)
		at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:726)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1201)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1191)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:747)
		at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:209)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:410)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:872)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.startup.Catalina.start(Catalina.java:736)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:569)
		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
07-Jan-2026 21:12:29.748 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.cipres.treebase.web.listeners.StartupListener]
	java.lang.ClassNotFoundException: org.cipres.treebase.web.listeners.StartupListener
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1351)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1160)
		at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:484)
		at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:466)
		at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3974)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4489)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:597)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:569)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:608)
		at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677)
		at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1836)
		at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
		at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:572)
		at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:463)
		at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)
		at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
		at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109)
		at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389)
		at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:774)
		at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:726)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1201)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1191)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:747)
		at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:209)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:410)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:872)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.startup.Catalina.start(Catalina.java:736)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:569)
		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
07-Jan-2026 21:12:29.748 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [net.sf.navigator.menu.MenuContextListener]
	java.lang.ClassNotFoundException: net.sf.navigator.menu.MenuContextListener
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1351)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1160)
		at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:484)
		at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:466)
		at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3974)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4489)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:597)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:569)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:608)
		at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677)
		at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1836)
		at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
		at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:572)
		at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:463)
		at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)
		at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
		at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109)
		at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389)
		at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:774)
		at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:726)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1201)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1191)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:747)
		at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:209)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:410)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:872)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.startup.Catalina.start(Catalina.java:736)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:569)
		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
07-Jan-2026 21:12:29.748 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Error configuring application listener of class [org.cipres.treebase.web.listeners.EventListener]
	java.lang.ClassNotFoundException: org.cipres.treebase.web.listeners.EventListener
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1351)
		at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1160)
		at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:484)
		at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:466)
		at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:142)
		at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3974)
		at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4489)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:597)
		at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:569)
		at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:608)
		at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:677)
		at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1836)
		at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
		at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:572)
		at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:463)
		at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576)
		at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309)
		at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109)
		at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389)
		at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:774)
		at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:726)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1201)
		at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1191)
		at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
		at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:82)
		at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
		at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:747)
		at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:209)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:410)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:872)
		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164)
		at org.apache.catalina.startup.Catalina.start(Catalina.java:736)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:569)
		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342)
		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
07-Jan-2026 21:12:29.748 SEVERE [main] org.apache.catalina.core.StandardContext.listenerStart Skipped installing application listeners due to previous error(s)

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot from localhost.*.log:

...

The issue is a missing JavaMelody JAR in WEB-INF/lib. This happens because the volume mount for JSP files might be interfering with the WEB-INF directory structure.

Verify the libraries were copied:

docker exec -it treebase-web-dev ls -la /usr/local/tomcat/webapps/treebase-web/WEB-INF/lib/ | grep javamelody

If the directory is empty or missing javamelody, restart the container to re-run the entrypoint script:

docker compose restart web-dev
docker compose logs -f web-dev

If it still fails, the issue is the volume mount overwriting WEB-INF. Check the docker-compose volume configuration:

grep -A5 "web-dev:" docker-compose.yml | grep -A10 volumes

The WEB-INF/lib and WEB-INF/classes are mounted as separate volumes to prevent this exact issue. If those volumes are empty, the entrypoint script needs to run successfully. Share the output of the first command and the entrypoint logs from the restart.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot I tried to start from scratch but the database sticks around so now I get this:

treebase-postgres  | 2026-01-07 21:46:52.033 UTC [63] ERROR:  relation "matrixelement_discretecharstate_id_idx" already exists
treebase-postgres  | 2026-01-07 21:46:52.033 UTC [63] STATEMENT:  CREATE INDEX matrixelement_discretecharstate_id_idx ON matrixelement(discretecharstate_id);
treebase-postgres  | psql:/docker-entrypoint-initdb.d/01-schema.sql:2529: ERROR:  relation "matrixelement_discretecharstate_id_idx" already exists

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot I tried to start from scratch but the database sticks around so now I get this:

...

The PostgreSQL volume persisted because docker compose down -v only removes volumes if they're not named. Use these commands to completely reset:

# Stop all containers
docker compose --profile development down

# Remove the named volume explicitly
docker volume rm treebase_postgres-data

# Or remove all unused volumes
docker volume prune -f

# Verify volumes are gone
docker volume ls | grep treebase

# Now start fresh
docker compose --profile development up --build

Alternatively, if you want to keep iterating without rebuilding the database each time, you can skip the schema re-initialization by removing and recreating only the web container:

# Just restart the web container (keeps database intact)
docker compose restart web-dev
docker compose logs -f web-dev

This is useful once the database is properly initialized and you're just troubleshooting the application startup.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot it still happens. Are we sure there isn't a mistake in the SQL?

treebase-postgres  | psql:/docker-entrypoint-initdb.d/01-schema.sql:2529: ERROR:  relation "matrixelement_discretecharstate_id_idx" already exists
treebase-postgres  | 2026-01-07 21:59:36.023 UTC [63] ERROR:  relation "matrixelement_discretecharstate_id_idx" already exists
treebase-postgres  | 2026-01-07 21:59:36.023 UTC [63] STATEMENT:  CREATE INDEX matrixelement_discretecharstate_id_idx ON matrixelement(discretecharstate_id);

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot it still happens. Are we sure there isn't a mistake in the SQL?

...

Good catch! Fixed in commit 800e2af. The SQL schema file had a duplicate CREATE INDEX statement on lines 2527 and 2529 - the same index was being created twice:

CREATE INDEX matrixelement_discretecharstate_id_idx ON matrixelement(discretecharstate_id);

Removed the duplicate line. Now the database initialization should complete successfully without errors.

@rvosa
Copy link
Contributor

rvosa commented Jan 7, 2026

@copilot ok, we're back to java.lang.ClassNotFoundException: net.bull.javamelody.SessionListener. How come these volumes are size 0?
Screenshot 2026-01-07 at 23 05 45

Co-authored-by: rvosa <106490+rvosa@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot ok, we're back to java.lang.ClassNotFoundException: net.bull.javamelody.SessionListener. How come these volumes are size 0?
<img width="1624" height="971" alt="Screenshot 2026-01-07 at 23...

Fixed in commit 466733f. The volumes were 0 Bytes because of a mount conflict.

The Problem:
The entire ./treebase-web/src/main/webapp directory was mounted to /usr/local/tomcat/webapps/treebase-web, which overwrote the WEB-INF subdirectory that the entrypoint script populated with compiled classes and JAR libraries.

The Solution:
Changed docker-compose.yml to mount webapp subdirectories individually (decorators, images, scripts, styles, common, help, test) plus individual root-level JSP files, while excluding WEB-INF. This allows:

  • The entrypoint script to populate WEB-INF/classes and WEB-INF/lib volumes
  • JSP files to remain editable locally with hot-reload

After pulling this commit, remove the old volumes and restart:

docker compose --profile development down
docker volume rm treebase_web-inf-classes treebase_web-inf-lib
docker compose --profile development up --build

The volumes should now populate with compiled classes and JAR files.

@rvosa rvosa marked this pull request as ready for review January 7, 2026 22:15
@rvosa rvosa merged commit 1d1baf8 into master Jan 7, 2026
3 checks passed
@rvosa rvosa deleted the copilot/add-dockerfile-for-web-app branch January 7, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants