====== Systemd Service Script ====== **General Information** Creating a systemd until file (service script). **Checklist** * Distro(s): Enterprise Linux 7 ---- ====== Unit File Reference ====== * /usr/lib/systemd/system => system unit configuration files (default with system) * /etc/systemd/system => additional configuration files (downloaded or custom) ---- ====== Implementation ====== * Download the code * Modify each section to make sense for your service * Copy to /etc/systemd/system/.service * Start your servicesystemctl start * **Note: This will fail if the ExecStart script/program does not have the executable permissions or if the EnvironmentFile config file does not exist.** ---- ====== The Service Unit File ====== [Unit] Description=My Awesome Program After=syslog.target [Service] Type=simple EnvironmentFile=/etc/myprog.d/config ExecStart=/usr/local/bin/myprog.sh Restart=on-abort [Install] WantedBy=multi-user.target * Section: Unit * Description => Displays near the top of output on "systemctl status myprog.service" * After => can be any valid systemd unit (.target, .service, etc) * **Multiple units are space separated** * Another common use target is: After=network.target * See all: systemctl -t target --all * Section: Service * Type => The process and daemon behavior * simple -> default if Type is not set, but ExecStart is. Main process specified in ExecStart line. * forking -> service forks a child process and the parent process exits * oneshot -> default if Type and ExecStart are not set. Process is short lived, systemd will wait for the process to exit before continuting with other units. * notify -> service will issue a notification when it has finished starting. Systemd will wait before processing other units * EnvironmentFile => Configuration file to load * ExecStart => Executable to start * Restart => Auto restarts the program if an un-handled exit error occurs * Section: Install * WantedBy => If enabled, start under which target ---- ===== Example: Test Script ===== This is the script that was used to test the custom systemd service unit file. **NOTE:** The script being launched MUST have the "#!/bin/bash" line first or the unit file will fail. (Cannot have a standard comment line as the first line) \\ /usr/local/bin/myprog.sh #!/bin/bash echo "Welcome to my program" logger -p info "$0 has started on $(date)" while true; do logger -p info "$0 is still running..." sleep 30 done * **Note: Ensure this script is executable, or the service will fail to start.** ---- ==== Example: Service Status ==== [root@server1 system]# systemctl start myprog.service [root@server1 system]# systemctl status myprog.service ● myprog.service - My Awesome Program Loaded: loaded (/etc/systemd/system/myprog.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2016-01-24 10:30:08 CST; 6s ago Main PID: 17602 (myprog.sh) CGroup: /system.slice/myprog.service ├─17602 /bin/bash /usr/local/bin/myprog.sh └─17608 sleep 30 Jan 24 10:30:08 server1.local systemd[1]: Started My Awesome Program. Jan 24 10:30:08 server1.local systemd[1]: Starting My Awesome Program... Jan 24 10:30:08 server1.local myprog.sh[17602]: Welcome to my program ---- ==== Example: Logs ==== journalctl -f -- Logs begin at Fri 2015-12-25 22:36:05 CST. -- Jan 24 10:30:08 server1.local systemd[1]: Starting My Awesome Program... Jan 24 10:30:08 server1.local myprog.sh[17602]: Welcome to my program Jan 24 10:30:08 server1.local logger[17605]: /usr/local/bin/myprog.sh has started on Sun Jan 24 10:30:08 CST 2016 Jan 24 10:30:08 server1.local logger[17606]: /usr/local/bin/myprog.sh is still running... Jan 24 10:30:38 server1.local logger[17683]: /usr/local/bin/myprog.sh is still running... Jan 24 10:31:08 server1.local logger[17693]: /usr/local/bin/myprog.sh is still running... ---- ===== Example: Docker Compose ===== Putting docker-compose commands into a service. /etc/systemd/system/docker-compose.service [Unit] Description=Docker Compose Containers Requires=docker.service After=docker.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/docker-compose -f /data/docker/docker-compose.yml up -d ExecStop=/usr/local/bin/docker-compose -f /data/docker/docker-compose.yml down [Install] WantedBy=multi-user.target ---- ===== Example: Apache HTTPD Compiled ===== Creating a service unit file for a locally compiled and installed Apache web server. \\ /etc/systemd/system/httpd-local.service [Unit] Description=Apache Web Server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/usr/local/apache2/logs/httpd.pid ExecStart=/usr/local/apache2/bin/apachectl start ExecStop=/usr/local/apache2/bin/apachectl graceful-stop ExecReload=/usr/local/apache2/bin/apachectl graceful PrivateTmp=true LimitNOFILE=infinity [Install] WantedBy=multi-user.target \\ Reload systemdsystemctl daemon-reload \\ Enable/start servicesystemctl enable httpd-local systemctl start httpd-local ---- ====== Override File ====== Override files are used when you want to modify part or all of a RPM/system provided systemd unit file. Use over rides instead of directly modifying system unit files, as they could be reverted upon next related package update. System Provided unit files: /usr/lib/systemd/system/ ===== Override Example: docker service ===== System provided file to over ride: /usr/lib/systemd/system/docker.service * Create a directory to contain the over ride file (named after the original unit file name)mkdir /etc/systemd/system/docker.service.d/ * Create the over ride file/etc/systemd/system/docker.service.d/docker.conf [Service] EnvironmentFile= EnvironmentFile=-/etc/sysconfig/docker ExecStart= ExecStart=/usr/bin/dockerd $OPTIONS * Each variable with a blank assignment ('EnvironmentFile=') clears that variable. If you did not put the assignment to nothing line, the variables would be appended to the built in values. * Reload the systemd daemon for the override file to be picked upsystemctl daemon-reload * Restart the service ===== Override Example: rpcbind service ===== System provided file to over ride: /usr/lib/systemd/system/rpcbind.service * Create a directory to contain the over ride file (named after the original unit file name, but add a ".d" for directory)mkdir /etc/systemd/system/rpcbind.service.d/ * Create the over ride file (NAME.conf)/etc/systemd/system/rpcbind.service.d/rpcbind.conf [Service] ExecStart= ExecStart=/sbin/rpcbind $RPCBIND_ARGS * Each variable with a blank assignment ('EnvironmentFile=') clears that variable. If you did not put the assignment to nothing line, the variables would be appended to the built in values. * Reload the systemd daemon for the override file to be picked upsystemctl daemon-reload * Restart the service ----