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).