Debian: rc.local
As pointed out elsewhere, it becomes moderately unclean to use rc-local.service under systemd.
It is theoretically possible that your distribution will not enable it. (I think this is not common, e.g. because disabling the same build option also removes poweroff / reboot commands that a lot of people use). The semantics are not entirely clear. Systemd defines rc-local.service one way, but Debian provides a drop-in file which alters at least one important setting. rc-local.service can often work well. If you're worried about the above, all you need to do is make your own copy of it! Here's the magic:
# /etc/systemd/system/my-startup.service [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/libexec/my-startup-script [Install] WantedBy=multi-user.target
I don't think you need to understand every single detail[*], but there are two things you need to know here.
You need to enable this with
systemctl enable my-startup.service.
If your script has a dependency on any other service, including network-online.target, you must declare it. E.g. add a [Unit] section, with the lines Wants=network-online.target and After=network-online.target.
You don't need to worry about dependencies on "early boot" services - specifically, services that are already ordered before basic.target. Services like my-startup.service are automatically ordered after basic.target, unless they set DefaultDependencies=no.
If you're not sure whether one of your dependencies is an "early boot" service, one approach is to list the services that are ordered before basic.target, by running systemctl list-dependencies --after basic.target. (Note that's --after, not --before).
There are some considerations that I think also applied to pre-systemd rc.local:
You need to make sure your commands are not conflicting with another program that tries to control the same thing. It is best not to start long-running programs aka daemons from rc.local. [*] I used Type=oneshot + RemainAfterExit=yes because it makes more sense for most one-shot scripts. It formalizes that you will run a series of commands, that my-startup will be shown as "active" once they have completed, and that you will not start a daemon.