Skip to content

Commit

Permalink
Improve upgrade workflow for embedded Tomcat (#752)
Browse files Browse the repository at this point in the history
- Remove 'server' directory from embedded labkey
- Add application.properties for distributions
- Detect when to upgrade an existing embedded deployment
  • Loading branch information
labkey-tchad authored Mar 12, 2024
1 parent d3fdc23 commit adb39ba
Show file tree
Hide file tree
Showing 10 changed files with 512 additions and 159 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ windowsProteomicsBinariesVersion=1.0
# The current version numbers for the gradle plugins.
artifactoryPluginVersion=4.31.9
gradleNodePluginVersion=3.5.1
gradlePluginsVersion=2.3.0
gradlePluginsVersion=2.6.0
owaspDependencyCheckPluginVersion=8.4.3
versioningPluginVersion=1.1.2

Expand Down
142 changes: 29 additions & 113 deletions server/configs/application.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## These properties are used for development and test deployments.
## Many properties here will be filled in and uncommented by the Gradle 'pickPg' and 'pickMssql' tasks
## See '/webapps/application.properties' for more examples

server.port=@@serverPort@@

## To use ssl, update the properties below for your local installation
Expand All @@ -8,16 +12,16 @@ server.port=@@serverPort@@
#server.ssl.key-alias=tomcat
#server.ssl.key-store=@@keyStore@@
#server.ssl.key-store-password=@@keyStorePassword@@
# Typically either PKCS12 or JKS
## Typically either PKCS12 or JKS
#server.ssl.key-store-type=PKCS12
#server.ssl.ciphers=HIGH:!ADH:!EXP:!SSLv2:!SSLv3:!MEDIUM:!LOW:!NULL:!aNULL

# HTTP-only port for servers that need to handle both HTTPS (configure via server.port and server.ssl above) and HTTP
## HTTP-only port for servers that need to handle both HTTPS (configure via server.port and server.ssl above) and HTTP
#context.httpPort=8080

# Database connections. All deployments need a labkeyDataSource as their primary database. Add additional external
# data sources by specifying the required properties (at least driverClassName, url, username, and password)
# with a prefix of context.resources.jdbc.<dataSourceName>.
## Database connections. All deployments need a labkeyDataSource as their primary database. Add additional external
## data sources by specifying the required properties (at least driverClassName, url, username, and password)
## with a prefix of context.resources.jdbc.<dataSourceName>.
context.resources.jdbc.labkeyDataSource.type=javax.sql.DataSource
context.resources.jdbc.labkeyDataSource.driverClassName=@@jdbcDriverClassName@@
context.resources.jdbc.labkeyDataSource.url=@@jdbcURL@@
Expand All @@ -39,19 +43,6 @@ context.resources.jdbc.labkeyDataSource.validationQuery=SELECT 1
#useLocalBuild#context.webAppLocation=@@pathToServer@@/build/deploy/labkeyWebapp
context.encryptionKey=@@encryptionKey@@

# By default, we deploy to the root context path. However, some servers have historically used /labkey or even /cpas
#context.contextPath=/labkey

# Using a legacy context path provides backwards compatibility with old deployments. A typical use case would be to
# deploy to the root context (the default) and configure /labkey as the legacy path. GETs will be redirected.
# All other methods (POSTs, PUTs, etc) will be handled server-side via a servlet forward.
#context.legacyContextPath=/labkey

# Other webapps to be deployed, most commonly to deliver a set of static files. The context path to deploy into is the
# property name after the "context.additionalWebapps." prefix, and the value is the location of the webapp on disk
#context.additionalWebapps.firstContextPath=/my/webapp/path
#context.additionalWebapps.secondContextPath=/my/other/webapp/path

#context.oldEncryptionKey=
#context.requiredModules=
#context.pipelineConfig=/path/to/pipeline/config/dir
Expand All @@ -62,107 +53,32 @@ context.encryptionKey=@@encryptionKey@@
mail.smtpHost=@@smtpHost@@
mail.smtpPort=@@smtpPort@@
mail.smtpUser=@@smtpUser@@
# mail.smtpFrom=@@smtpFrom@@
# mail.smtpPassword=@@smtpPassword@@
# mail.startTlsEnable=@@smtpStartTlsEnable@@
# mail.smtpSocketFactoryClass=@@smtpSocketFactoryClass@@
# mail.smtpAuth=@@smtpAuth@@

# Optional - JMS configuration for remote ActiveMQ message management for distributed pipeline jobs
# https://www.labkey.org/Documentation/wiki-page.view?name=jmsQueue
#context.resources.jms.ConnectionFactory.type=org.apache.activemq.ActiveMQConnectionFactory
#context.resources.jms.ConnectionFactory.factory=org.apache.activemq.jndi.JNDIReferenceFactory
#context.resources.jms.ConnectionFactory.description=JMS Connection Factory
# Use an in-process ActiveMQ queue
#context.resources.jms.ConnectionFactory.brokerURL=vm://localhost?broker.persistent=false&broker.useJmx=false
# Use an out-of-process ActiveMQ queue
#context.resources.jms.ConnectionFactory.brokerURL=tcp://localhost:61616
#context.resources.jms.ConnectionFactory.brokerName=LocalActiveMQBroker

# Optional - LDAP configuration for LDAP group/user synchronization
# https://www.labkey.org/Documentation/wiki-page.view?name=LDAP_sync
#context.resources.ldap.ConfigFactory.type=org.labkey.premium.ldap.LdapConnectionConfigFactory
#context.resources.ldap.ConfigFactory.factory=org.labkey.premium.ldap.LdapConnectionConfigFactory
#context.resources.ldap.ConfigFactory.host=myldap.mydomain.com
#context.resources.ldap.ConfigFactory.port=389
#context.resources.ldap.ConfigFactory.principal=cn=read_user
#context.resources.ldap.ConfigFactory.credentials=read_user_password
#context.resources.ldap.ConfigFactory.useTls=false
#context.resources.ldap.ConfigFactory.useSsl=false
#context.resources.ldap.ConfigFactory.sslProtocol=SSLv3

#useLocalBuild#spring.devtools.restart.additional-paths=@@pathToServer@@/build/deploy/modules,@@pathToServer@@/build/deploy/embedded/config

# HTTP session timeout for users - defaults to 30 minutes
#server.servlet.session.timeout=30m
#mail.smtpFrom=@@smtpFrom@@
#mail.smtpPassword=@@smtpPassword@@
#mail.startTlsEnable=@@smtpStartTlsEnable@@
#mail.smtpSocketFactoryClass=@@smtpSocketFactoryClass@@
#mail.smtpAuth=@@smtpAuth@@

#useLocalBuild#spring.devtools.restart.additional-paths=@@pathToServer@@/build/deploy/modules
# Use a trigger file for smoother restart behavior
#useLocalBuild#spring.devtools.restart.trigger-file=.restartTrigger

## HTTP session timeout for users - defaults to 30 minutes
#server.servlet.session.timeout=30m

#Enable shutdown endpoint
## Enable shutdown endpoint
management.endpoint.shutdown.enabled=true
# turn off other endpoints
## turn off other endpoints
management.endpoints.enabled-by-default=false
# allow access via http
## allow access via http
management.endpoints.web.exposure.include=*
# Use a separate port for management endpoints. Required if LabKey is using default (ROOT) context path
## Use a separate port for management endpoints. Required if LabKey is using default (ROOT) context path
management.server.port=@@shutdownPort@@

# Don't show the Spring banner on startup
## Don't show the Spring banner on startup
spring.main.banner-mode=off
#logging.config=path/to/alternative/log4j2.xml

# Optional - JMS configuration for remote ActiveMQ message management for distributed pipeline jobs
# https://www.labkey.org/Documentation/wiki-page.view?name=jmsQueue
#context.resources.jms.name=jms/ConnectionFactory
#context.resources.jms.type=org.apache.activemq.ActiveMQConnectionFactory
#context.resources.jms.factory=org.apache.activemq.jndi.JNDIReferenceFactory
#context.resources.jms.description=JMS Connection Factory
#context.resources.jms.brokerURL=vm://localhost?broker.persistent=false&broker.useJmx=false
#context.resources.jms.brokerName=LocalActiveMQBroker

# Turn on JSON-formatted HTTP access logging to stdout. See issue 48565
# https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#JSON_Access_Log_Valve
#jsonaccesslog.enabled=true

# Optional configuration, modeled on the non-JSON Spring Boot properties
# https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server.server.tomcat.accesslog.buffered
#jsonaccesslog.pattern=%h %t %m %U %s %b %D %S "%{Referer}i" "%{User-Agent}i" %{LABKEY.username}s
#jsonaccesslog.condition-if=attributeName
#jsonaccesslog.condition-unless=attributeName

# Define one or both of 'csp.report' and 'csp.enforce' to enable Content Security Policy (CSP) headers
# Do not copy-and-paste these examples for any production environment without understanding the meaning of each directive!

# example usage 1 - very strict, disallows 'external' websites, disallows unsafe-inline, but only reports violations (does not enforce)

#csp.report=\
# default-src 'self';\
# connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ;\
# object-src 'none' ;\
# style-src 'self' 'unsafe-inline' ;\
# img-src 'self' data: ;\
# font-src 'self' data: ;\
# script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}';\
# base-uri 'self' ;\
# upgrade-insecure-requests ;\
# frame-ancestors 'self' ;\
# report-uri https://www.labkey.org/admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;

# example usage 2 - less strict but enforces directives, (NOTE: unsafe-inline is still required for many modules)

#csp.enforce=\
# default-src 'self' https: ;\
# connect-src 'self' https: ${LABKEY.ALLOWED.CONNECTIONS};\
# object-src 'none' ;\
# style-src 'self' https: 'unsafe-inline' ;\
# img-src 'self' data: ;\
# font-src 'self' data: ;\
# script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}';\
# base-uri 'self' ;\
# upgrade-insecure-requests ;\
# frame-ancestors 'self' ;\
# report-uri https://www.labkey.org/admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;

# Default CSP for TeamCity and dev deployments

## Default CSP for TeamCity and dev deployments
csp.report=\
default-src 'self' https: http: ;\
connect-src 'self' localhost:* ws: ${LABKEY.ALLOWED.CONNECTIONS} ;\
Expand All @@ -175,10 +91,10 @@ csp.report=\
frame-ancestors 'self' ;\
report-uri /admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;

# Use a non-temp directory for tomcat
## Use a non-temp directory for tomcat
server.tomcat.basedir=.

# Enable tomcat access log
## Enable tomcat access log
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %S %I "%{Referrer}i" "%{User-Agent}i" %{LABKEY.username}s
7 changes: 7 additions & 0 deletions server/configs/webapps/embedded/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Thank you for downloading LabKey Server. For more information about...

- Installing LabKey Server. See https://www.labkey.org/Documentation/wiki-page.view?name=embeddedConfig

- Upgrading LabKey Server. See https://www.labkey.org/Documentation/wiki-page.view?name=embeddedUpgrade

- Using LabKey Server. See https://www.labkey.org/Documentation/project-begin.view
163 changes: 163 additions & 0 deletions server/configs/webapps/embedded/config/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
server.port=8080

## To use ssl, update the properties below for your local installation

#server.ssl.enabled=true
#server.ssl.enabled-protocols=TLSv1.3,TLSv1.2,TLSv1.1
#server.ssl.protocol=TLS
#server.ssl.key-alias=tomcat
#server.ssl.key-store=@@keyStore@@
#server.ssl.key-store-password=@@keyStorePassword@@
## Typically either PKCS12 or JKS
#server.ssl.key-store-type=PKCS12
#server.ssl.ciphers=HIGH:!ADH:!EXP:!SSLv2:!SSLv3:!MEDIUM:!LOW:!NULL:!aNULL

## HTTP-only port for servers that need to handle both HTTPS (configure via server.port and server.ssl above) and HTTP
#context.httpPort=8080

## Database connections. All deployments need a labkeyDataSource as their primary database. Add additional external
## data sources by specifying the required properties (at least driverClassName, url, username, and password)
## with a prefix of context.resources.jdbc.<dataSourceName>.
context.resources.jdbc.labkeyDataSource.type=javax.sql.DataSource
context.resources.jdbc.labkeyDataSource.driverClassName=@@jdbcDriverClassName@@
context.resources.jdbc.labkeyDataSource.url=@@jdbcURL@@
context.resources.jdbc.labkeyDataSource.username=@@jdbcUser@@
context.resources.jdbc.labkeyDataSource.password=@@jdbcPassword@@
context.resources.jdbc.labkeyDataSource.maxTotal=50
context.resources.jdbc.labkeyDataSource.maxIdle=10
context.resources.jdbc.labkeyDataSource.maxWaitMillis=120000
context.resources.jdbc.labkeyDataSource.accessToUnderlyingConnectionAllowed=true
context.resources.jdbc.labkeyDataSource.validationQuery=SELECT 1
#context.resources.jdbc.labkeyDataSource.logQueries=true
#context.resources.jdbc.labkeyDataSource.displayName=Alternate Display Name

#context.resources.jdbc.@@extraJdbcDataSource@@.driverClassName=@@extraJdbcDriverClassName@@
#context.resources.jdbc.@@extraJdbcDataSource@@.url=@@extraJdbcUrl@@
#context.resources.jdbc.@@extraJdbcDataSource@@.username=@@extraJdbcUsername@@
#context.resources.jdbc.@@extraJdbcDataSource@@.password=@@extraJdbcPassword@@

context.encryptionKey=@@encryptionKey@@

## By default, we deploy to the root context path. However, some servers have historically used /labkey or even /cpas
#context.contextPath=/labkey

## Using a legacy context path provides backwards compatibility with old deployments. A typical use case would be to
## deploy to the root context (the default) and configure /labkey as the legacy path. GETs will be redirected.
## All other methods (POSTs, PUTs, etc) will be handled server-side via a servlet forward.
#context.legacyContextPath=/labkey

## Other webapps to be deployed, most commonly to deliver a set of static files. The context path to deploy into is the
## property name after the "context.additionalWebapps." prefix, and the value is the location of the webapp on disk
#context.additionalWebapps.firstContextPath=/my/webapp/path
#context.additionalWebapps.secondContextPath=/my/other/webapp/path

#context.oldEncryptionKey=
#context.requiredModules=
#context.pipelineConfig=/path/to/pipeline/config/dir
#context.serverGUID=
#context.bypass2FA=true
#context.workDirLocation=/path/to/desired/workDir

mail.smtpHost=@@smtpHost@@
mail.smtpPort=@@smtpPort@@
mail.smtpUser=@@smtpUser@@
#mail.smtpFrom=@@smtpFrom@@
#mail.smtpPassword=@@smtpPassword@@
#mail.startTlsEnable=@@smtpStartTlsEnable@@
#mail.smtpSocketFactoryClass=@@smtpSocketFactoryClass@@
#mail.smtpAuth=@@smtpAuth@@

## Optional - JMS configuration for remote ActiveMQ message management for distributed pipeline jobs
## https://www.labkey.org/Documentation/wiki-page.view?name=jmsQueue
#context.resources.jms.ConnectionFactory.type=org.apache.activemq.ActiveMQConnectionFactory
#context.resources.jms.ConnectionFactory.factory=org.apache.activemq.jndi.JNDIReferenceFactory
#context.resources.jms.ConnectionFactory.description=JMS Connection Factory
## Use an in-process ActiveMQ queue
#context.resources.jms.ConnectionFactory.brokerURL=vm://localhost?broker.persistent=false&broker.useJmx=false
## Use an out-of-process ActiveMQ queue
#context.resources.jms.ConnectionFactory.brokerURL=tcp://localhost:61616
#context.resources.jms.ConnectionFactory.brokerName=LocalActiveMQBroker

## Optional - LDAP configuration for LDAP group/user synchronization
## https://www.labkey.org/Documentation/wiki-page.view?name=LDAP_sync
#context.resources.ldap.ConfigFactory.type=org.labkey.premium.ldap.LdapConnectionConfigFactory
#context.resources.ldap.ConfigFactory.factory=org.labkey.premium.ldap.LdapConnectionConfigFactory
#context.resources.ldap.ConfigFactory.host=myldap.mydomain.com
#context.resources.ldap.ConfigFactory.port=389
#context.resources.ldap.ConfigFactory.principal=cn=read_user
#context.resources.ldap.ConfigFactory.credentials=read_user_password
#context.resources.ldap.ConfigFactory.useTls=false
#context.resources.ldap.ConfigFactory.useSsl=false
#context.resources.ldap.ConfigFactory.sslProtocol=SSLv3

## HTTP session timeout for users - defaults to 30 minutes
#server.servlet.session.timeout=30m

## Enable shutdown endpoint. Allows server to be shutdown with a POST to 'localhost:8081/actuator/shutdown
#management.endpoint.shutdown.enabled=true
#management.endpoints.enabled-by-default=false
#management.endpoints.web.exposure.include=*
#management.server.port=8081

## Don't show the Spring banner on startup
spring.main.banner-mode=off
#logging.config=path/to/alternative/log4j2.xml

## Optional - JMS configuration for remote ActiveMQ message management for distributed pipeline jobs
## https://www.labkey.org/Documentation/wiki-page.view?name=jmsQueue
#context.resources.jms.name=jms/ConnectionFactory
#context.resources.jms.type=org.apache.activemq.ActiveMQConnectionFactory
#context.resources.jms.factory=org.apache.activemq.jndi.JNDIReferenceFactory
#context.resources.jms.description=JMS Connection Factory
#context.resources.jms.brokerURL=vm://localhost?broker.persistent=false&broker.useJmx=false
#context.resources.jms.brokerName=LocalActiveMQBroker

## Turn on JSON-formatted HTTP access logging to stdout. See issue 48565
## https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#JSON_Access_Log_Valve
#jsonaccesslog.enabled=true

## Optional configuration, modeled on the non-JSON Spring Boot properties
## https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server.server.tomcat.accesslog.buffered
#jsonaccesslog.pattern=%h %t %m %U %s %b %D %S "%{Referer}i" "%{User-Agent}i" %{LABKEY.username}s
#jsonaccesslog.condition-if=attributeName
#jsonaccesslog.condition-unless=attributeName

## Define one or both of 'csp.report' and 'csp.enforce' to enable Content Security Policy (CSP) headers
## Do not use these examples for any production environment without understanding the meaning of each directive!

## example usage 1 - very strict, disallows 'external' websites, disallows unsafe-inline, but only reports violations (does not enforce)

#csp.report=\
# default-src 'self';\
# connect-src 'self' ${LABKEY.ALLOWED.CONNECTIONS} ;\
# object-src 'none' ;\
# style-src 'self' 'unsafe-inline' ;\
# img-src 'self' data: ;\
# font-src 'self' data: ;\
# script-src 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}';\
# base-uri 'self' ;\
# upgrade-insecure-requests ;\
# frame-ancestors 'self' ;\
# report-uri https://www.labkey.org/admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;

## example usage 2 - less strict but enforces directives, (NOTE: unsafe-inline is still required for many modules)

#csp.enforce=\
# default-src 'self' https: ;\
# connect-src 'self' https: ${LABKEY.ALLOWED.CONNECTIONS};\
# object-src 'none' ;\
# style-src 'self' https: 'unsafe-inline' ;\
# img-src 'self' data: ;\
# font-src 'self' data: ;\
# script-src 'unsafe-inline' 'unsafe-eval' 'strict-dynamic' 'nonce-${REQUEST.SCRIPT.NONCE}';\
# base-uri 'self' ;\
# upgrade-insecure-requests ;\
# frame-ancestors 'self' ;\
# report-uri https://www.labkey.org/admin-contentsecuritypolicyreport.api?${CSP.REPORT.PARAMS} ;


## Enable tomcat access log
#server.tomcat.basedir=.
#server.tomcat.accesslog.enabled=true
#server.tomcat.accesslog.directory=logs
#server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D %S %I "%{Referrer}i" "%{User-Agent}i" %{LABKEY.username}s
28 changes: 28 additions & 0 deletions server/configs/webapps/service.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
set LABKEY_HOME=C:\labkey\labkey
set JAVA_HOME=C:\labkey\apps\java\jdk-17.0.9+9

prunsrv.exe //IS//tc10embedded ^
--DisplayName "LabKey Tomcat 10 Embedded - tc10embedded" ^
--Description "LabKey Tomcat 10 Embedded" ^
--Install "%LABKEY_HOME%\prunsrv.exe" ^
--LogPath "%LABKEY_HOME%\logs" ^
--StdOutput auto ^
--StdError auto ^
--Classpath "%LABKEY_HOME%\labkeyServer.jar" ^
--Jvm "%JAVA_HOME%\bin\server\jvm.dll" ^
--StartMode jvm ^
--StopMode jvm ^
--StartPath "%LABKEY_HOME%" ^
--StopPath "%LABKEY_HOME%" ^
--StartParams start ^
--StartClass "org.springframework.boot.loader.launch.JarLauncher" ^
--StopParams stop ^
--StopMethod stop ^
--StopClass "java.lang.System" ^
--StopTimeout 60 ^
--Startup manual ^
--LogLevel Debug ^
--JvmOptions "-Djava.io.tmpdir=%LABKEY_HOME%\tomcat-tmp;-XX:+HeapDumpOnOutOfMemoryError;-XX:HeapDumpPath=%LABKEY_HOME%\tomcat-tmp;-DterminateOnStartupFailure=true;%JvmArgs%" ^
--JvmOptions9 "--add-opens=java.base/java.lang=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" ^
--JvmMs 2048 ^
--JvmMx 2048
Loading

0 comments on commit adb39ba

Please sign in to comment.