It is much more straightforward to use and with less surprises. The limits actually do what they say the do.
It also takes care of process lifecycle. And logs by default. It's preferable in every way.
What it doesn't do is manipulate and transfer file system images, that's outside the scope. Which is probably the right design. The whole thing of having Docker manipulate images for you was a strange decision and makes CI/CD unnecessarily complicated.
I got an application, I want to specify where the internal /etc/foo and /data lives outside the "systemd-container" and I want to map some ports to the internal IP.
There is plenty of examples in the documentation. The man page (man systemd-nspawn) is short and to the point.
As for your example,for regular daemons you probably want to use plain old unit files. You map ports with "Port=" and bind filesystems with "Bind=" ("/outside/data:/data" in your example). Again, plenty of examples in the documentation and in the Gentoo/Arch wikis which are excellent.
It also includes examples working with (not against) SELinux. Lots of other parts of the systemd family is nasty and full of surprises but this one pretty straightforward. systemd was built on cgroups from the ground up and it makes administering them fairly trivial.
This particular template we're not really worried about mem/cpu limits so that isn't in there. Authbind is in there to allow it to grab lower ports, but this particular app does not.
It also takes care of process lifecycle. And logs by default. It's preferable in every way.
What it doesn't do is manipulate and transfer file system images, that's outside the scope. Which is probably the right design. The whole thing of having Docker manipulate images for you was a strange decision and makes CI/CD unnecessarily complicated.