On a CentOS7 server I have an application stack composed by a Tomcat web server and a MySQL DB server, both installed on the same VM.
I would like them to start and stop together in this order:
START: MySQL--> Tomcat STOP: Tomcat-->MySQL
Reading systemd unit documentation, I managed to get them start together with Requires=
directive, but when I stop tomcat with systemctl stop tomcat.service, MySQL keeps on running. On system logs I noticed that it does not even try to stop MySQL, so there must be something wrong with the systemd unit.
Here is my unit:
# Systemd unit file for tomcat [Unit] Description=Apache Tomcat Web Application Container After=syslog.target network.target mysql.service Requires=mysql.service [Service] Type=forking Environment=JAVA_HOME=/opt/jdk Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/bin/kill -15 $MAINPID User=tomcat Group=tomcat [Install] WantedBy=multi-user.target
Best Answer
What you are seeing here is the expected systemd behavior. The
Requires=
dependency will make suremysql.service
is started whenevertomcat.service
starts, but once started the two units are independent and one won't be stopped when the other is.If you really want
mysql.service
to be stopped whentomcat.service
is, you can use thePartOf=
directive which links units on stop and restart.For the example you described (having
mysql.service
stop whenevertomcat.service
is stopped), what you need is to addPartOf=tomcat.service
to the definition ofmysql.service
. Usually, the best way to do so is to use an override file, which you can do withsystemctl edit mysql.service
which will open a text editor with an empty file, then you can add this snippet to it:This will get saved in a file
/etc/systemd/system/mysql.service.d/override.conf
which becomes part ofmysql.service
, you can check that withsystemctl cat mysql.service
.After those changes and a
systemctl daemon-reload
, this should work as you expect...Regarding ordering, everything should work as you expect with the single
After=mysql.service
you have intomcat.service
, since the dependencies are respected in the reverse order when stopping services. (Which means, in this case,tomcat.service
will be stopped first, followed bymysql.service
.)Stopping units this way might not be always a good idea... Perhaps a slightly better approach is to create a separate
.target
unit to group all services you want to control together. Perhaps something likewebservices.target
.You would create that unit with contents such as:
And then have both
tomcat.service
andmysql.service
set aPartOf=webservices.target
, using the override mechanism described above.Enable the target unit with
systemctl enable webservices.target
, and then you can start and stop both services together withsystemctl start webservices.target
orsystemctl stop webservices.target
.