On any modern Linux, a service that will not start has already written down exactly why. It is in the journal, and the reason people say there is nothing in the logs is that they ran journalctl with no arguments and gave up at the size of it.

The five that do the work

journalctl -u nginx -n 50 --no-pager   # the last 50 lines for one unit
journalctl -u nginx -f                # follow it live
journalctl -u nginx --since "10 min ago"
journalctl -p err -b                  # errors only, this boot
journalctl -b -1                      # the boot BEFORE this one
-b -1 is the one to reach for after an unexplained reboot: it shows what the machine was saying just before it went down, which the current boot does not contain.

When a service will not start

systemctl status app --no-pager -l
journalctl -u app -n 100 --no-pager

status shows the exit code and the last few lines; the journal shows the rest. A unit that fails immediately is almost always a path, a permission, or a port already in use, and all three say so in plain words.

The journal on disk

By default it may be volatile - kept in memory and lost at reboot, which is precisely when you want it. Make it persistent.

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --disk-usage

Keep it from filling the disk

# /etc/systemd/journald.conf
SystemMaxUse=500M
MaxRetentionSec=1month
An application that writes its own file - Nginx access logs, PHP-FPM slow logs - is not in the journal. Those are in /var/log and rotated separately; see log rotation.