The following is a collection of reminders regarding its use. It was created using Tomcat 8, but most of this should apply to later versions as well.
bin/startup.bat
(.sh
for Linux)
bin/shutdown.bat
ROOT
application is here: http://localhost:8080/
Tomcat comes with default configuration. When changing that config, you should change the file minimally, and do only what you need. Leave the comments alone, for example, and don't rearrange things unnecessarily. Only then will a simple diff with the default config show where you've deviated from the defaults.
To understand and use Tomcat effectively during development, you need to understand two important ideas:
$CATALINA_HOME
: location of the Tomcat binary
$CATALINA_BASE
: location of the Tomcat instance
$CATALINA_BASE
is the same as $CATALINA_HOME
.
You can think of a Tomcat instance as a kind of mini-Tomcat. It mimics the same directory structure found in the binary install, and looks like this:
startup.bat [short scripts that you create] shutdown.bat conf [start with the same conf folder in the Tomcat binary] server.xml [main config; each instance needs its own shutdown port] web.xml [settings amalgamated with app web.xml] context.xml [settings amalgamated with app's context xml file] catalina.properties logging.properties tomcat-users.xml [used for simple access control] Catalina localhost [app context xml files, that point to your web app] [add/delete an xml file here is one way to deploy/undeploy an app] lib [database jar; jars shared between apps] logs webapps [not really needed for deployment, but it's an option] [instead, put a context file in conf/Catalina/localhost] work [compiled JSPs and whatnot]So, the idea is that someone on your team sets up an instance, and all of its config, and then the Tomcat instance is shared with the team. The start-stop scripts are short. They simply set up environment variables, and then start the Tomcat binary.
Reload of an app:
web.xml
(via WatchedResource
), or changes somewhere inside WEB-INF/classes
(via the reloadable
setting for the app's context xml)
Serializable
.
Redeploy of an app:
web.xml
, mark the web-app top level node as metadata-complete
.
If this is not done, then the container will need to scan upon startup every class and jar in your app, to search for annotations and web-fragment.xml
files.
That's slow.
reloadable
setting is not suitable for prod):
<Context docBase="/some/dir/" reloadable="true"> <Resource name="jdbc/MYDatabase" auth="Container" type="javax.sql.DataSource" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" username="someusername" password="somepassword" url="jdbc:sqlserver://my_database_server_url" maxTotal="10" maxIdle="5" /> </Context>The file is located in
../conf/Catalina/localhost/mywar.xml
.
(It can also be embedded in war file itself, at the conventional location META-INF/context.xml
.)
This will map the app to the URL localhost:8080/mywar
.
By default, it simply takes the path from the name of the file.
If the context points to a war file, instead of a directory, then by default Tomcat will explode the war into its webapps
directory.
Note the default naming convention used by Tomcat uses the same name (blah
, in the following example) in 3 places:
blah.war
conf
directory: conf/Catalina/localhost/blah.xml
localhost:8080/blah
conf/tomcat-users.xml
. Add the following:
<?xml version='1.0' encoding='utf-8'?/> <tomcat-users> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="admin" password="admin" roles="manager-gui, manager-script, manager-jmx, manager-status"/> </tomcat-users/>Next is the Manager app's context file. By default, it's located in
/webapps/manager/META-INF/context.xml
, and it defines an IP filter, that restricts it to the localhost
only.
You may need to change or remove that restriction.
<?xml version="1.0" encoding="UTF-8"?> <Context docBase="${catalina.home}/webapps/manager" antiResourceLocking="false" privileged="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1" /> </Context>Here, the
allow
param is actually a regular expression.
server.xml
(this is the main config file)
web.xml
(amalgamated with your web app's web.xml
)
context.xml
(amalgamated with your web app's context file)
logging.properties
(JDK loggers)
catalina.properties
server.xml
('#' means it's a default setting):
Connector.compression="on"
- gzip textual output from the server, if the client supports it (which, these days, they all do, in practice).
#Connector.URIEncoding="UTF-8"
Connector.disableUploadTimeout="false"
Connector.connectionUploadTimeout="600000"
#Connector.useBodyEncodingForURI="false"
#Connector.connectionTimeout="20000"
- defaults to 20 seconds in server.xml
#Connector.maxThreads="200"
#Connector.minSpareThreads="10"
#Connector.SSLEnabled="false"
- if true, you need to set other things as well: .scheme="https" .secure="true"
, port, and so on
#Host.autoDeploy="true"
- true in dev, false in prod
Host.deployOnStartup="false"
- false in dev, true in prod
Host.deployXml="false"
- deploy using xml files in META-INF/context.xml
, in the app, instead of outside the app
#Host.unpackWars="true"
- explode war files into directories; faster to serve files this way
Some settings in context.xml
:
Context.deployOnStartup="false"
- false in dev, true in prod
Context.reloadable="true"
- true in dev, false in prod (the default)
Context.logEffectiveWebXml="true"
- combines all settings: app web.xml
, app annotations, container settings; prod should always have this on; outputs to the catalina
log
Context.Parameter
- as context-param
in web.xml
, but without editing web.xml
; overrides web.xml
by default.
Context.Environment
- as above, but for data accessible by JNDI
Context.Listener
- hooks into Tomcat; could record startup times, for instance
Context.Manager
- in prod, Tomcat recommends changing from StandardManager
(the default) to PersistentManager
Context.Manager.Store
- needed by PersistentManager
, but not by StandardManager
myapp##001.war
).
Existing sessions continue to be handled by the old version of the app, while new sessions go to the new version of the app.
Users migrate over from the old world to the new world, simply by logging in again.
Of course, the idea is to have zero downtime during a production upgrade.
Things to consider:
Once you have a certificate in a local keystore file, edit server.xml
, and add a second Connector
, for use with SSL.
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="conf/mykeystorefile" keystorePass="changeIt"/>The above
Connector
is a second Connector
.
You leave the existing non-SSL Connector
in place.
The non-SSL Connector
will be used for apps that don't require SSL.
In addition, if an app does require SSL, and a request URL for that app erroneously uses HTTP (and not HTTPS),
then Tomcat will use the Connector.redirectPort
setting of the non-SSL Connector
, and the browser gets
redirected to the secured Connector
, running on a different port.
The keystoreFile
path can be absolute; if relative, it's relative to $CATALINA_BASE
.
Self-signed certificates can be used only informally: they encrypt traffic, but they can't help with authentication or authorization.
When you use them, your browser will give you a warning, and you'll need to explicitly instruct the browser to accept the certificate.
The default HTTPS port is 443, not 8443. A warning from the docs:
"special setup (outside the scope of this document) is necessary to run Tomcat on port numbers lower than 1024 on
many operating systems [eg Linux]."
After you've finished configuring Tomcat for SSL, restart Tomcat, and navigate to a URL in your app (changing http
to https
).