What this covers
Your VM comes with a JDK, Maven, Gradle, nginx and root access. Getting your application onto it is four things: build the artefact, give it its configuration, run it under systemd so it survives a reboot, and put nginx in front so the JVM is never exposed directly. Do it by hand once, then turn it into a script.
Before you start
Have your VM's address and your SSH key, and make sure your repository can be reached from the machine. If your application needs a database, create it first — it will not start without the connection details.
How to do it
- Connect over SSH and see what you have: java -version and mvn -v. The machine ships a Java toolchain. If your project also builds a JavaScript front end, install Node yourself — it is not preinstalled.
- Get your code onto the machine with git clone, or build elsewhere and copy the jar across. Either works.
- Write your configuration into an environment file such as /etc/myapp/myapp.env — database URL, credentials, port. Keep it out of the repository, set it to mode 640, and own it root:myapp so only the service account can read it.
- Build once by hand with mvn -B clean package, and confirm the jar is at the path you expect before going further.
- Run it in the foreground first: load the environment file, then java -jar target/myapp.jar. Configuration mistakes are obvious here and hard to find in the logs later. From a second session check curl 127.0.0.1:8080/actuator/health, then stop it.
- Create a system account for the application and copy the jar somewhere stable such as /opt/myapp. Do not run it as root, and do not run it out of your home directory.
- Write a systemd unit so it starts at boot and restarts on failure. Point EnvironmentFile at your env file, set MemoryMax, and pass -XX:MaxRAMPercentage so the JVM sizes its heap against that limit rather than the whole machine.
- Start it with sudo systemctl enable --now myapp and check systemctl status myapp. If it does not come up, journalctl -u myapp -n 50 will tell you why.
- Point nginx at it: serve any static files, proxy the rest to your app on 127.0.0.1, and run nginx -t before reloading.
- Check each hop in turn — the unit is active, the app answers on loopback, nginx answers on the VM, the site answers from your own computer. The first one that fails is where the problem is.
What our team checks
We look after the machine, the operating system, the JDK, TLS and backups. If the VM is healthy and the JDK is the version you asked for but your application will not start, that is nearly always its configuration — send us the time it happened and we will check the machine side with you.
Next step
Deploy by hand once, all the way through. Then script it, because your second deployment is an upgrade and it should be one command.