I've used pretty much this approach at a couple of places, mostly working with Java. A production server is a vanilla Red Hat machine with an aftermarket JDK at a known path. The deployment artifact is a zip file containing jar files (and anything else) and a shell script called run.sh. Deployment is copying, unzipping, and overwriting a symlink. A cron job or a systemd etc service starts it. CI is a cron job which pulls, runs build.sh, and copies build/distribution to an NFS server. It works.