Deploying Kotlin Application on VPS: Step-by-Step Guide for Advanced Users
Developing in Kotlin is only half the battle. True mastery is demonstrated when your application starts running in a production environment on your own VPS server. In this article, we will cover advanced techniques for deploying Kotlin applications: from building a fat JAR to setting up uninterrupted operation with systemd, a reverse proxy via Nginx, and automation through CI/CD. The material is intended for developers who are already familiar with the basics of Kotlin and want to reach a professional level.
1. Preparing a Production Build of a Kotlin Application
The first step is creating an optimized build. We use the shadow plugin for Gradle, which packages all dependencies into a single executable JAR file (fat JAR).
Add to build.gradle.kts:
plugins { kotlin("jvm") version "1.9.22" id("com.github.johnrengelman.shadow") version "8.1.1" application}
application { mainClass.set("com.example.MainKt")}
tasks.shadowJar { archiveBaseName.set("app") archiveClassifier.set("") archiveVersion.set("") minimize()}Build the JAR with the command:
./gradlew shadowJarAs a result, you will get the file build/libs/app.jar. For production, it is recommended to disable debug logs and configure the logging level via environment variables.
Example logback.xml configuration for production:
<configuration> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>/var/log/app/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>/var/log/app/app.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>
<root level="INFO"> <appender-ref ref="FILE"/> </root></configuration>2. Creating a systemd Service for Automatic Startup
To ensure the application starts automatically on system boot and restarts on failure, we use systemd. Create the file /etc/systemd/system/kotlin-app.service:
[Unit]Description=Kotlin Application ServiceAfter=network.target
[Service]Type=simpleUser=appuserGroup=appuserWorkingDirectory=/opt/kotlin-appExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /opt/kotlin-app/app.jarRestart=on-failureRestartSec=10StandardOutput=journalStandardError=journalEnvironment="APP_ENV=production"Environment="DB_URL=jdbc:postgresql://localhost:5432/mydb"
[Install]WantedBy=multi-user.targetAfter creating the file, run:
sudo systemctl daemon-reloadsudo systemctl enable kotlin-appsudo systemctl start kotlin-appCheck the status:
sudo systemctl status kotlin-appLogs can be viewed via journalctl -u kotlin-app -f.
3. Configuring Nginx as a Reverse Proxy with SSL
Nginx will provide load balancing, caching, and HTTPS. Install Nginx and Certbot:
sudo apt updatesudo apt install nginx certbot python3-certbot-nginxCreate the configuration /etc/nginx/sites-available/kotlin-app:
server { listen 80; server_name yourdomain.com; return 301 https://$server_name$request_uri;}
server { listen 443 ssl http2; server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letse