DEV Community

Cover image for Deploy a Spring Boot File Server on a Free VPS (Step-by-Step Guide)
boiler_agents
boiler_agents

Posted on • Edited on

Deploy a Spring Boot File Server on a Free VPS (Step-by-Step Guide)

I wanted a simple way to host a file server that I could control myself—no third-party restrictions, no monthly bill. If that sounds like something you’d use, this walkthrough will help you do the same. By the end, you’ll have a Spring Boot file server running on a free VPS, protected by HTTPS, and tested with Postman.


What you’ll take away

  • Spin up a Spring Boot file-server boilerplate on a VPS.
  • Use Nginx as a reverse proxy and secure it with Let’s Encrypt.
  • Run the service either with systemd or inside Docker.
  • Confirm everything works using the included Postman collection.

Who this guide is for

If you’re the type who likes tinkering and would rather own your infrastructure than rely on Dropbox or Google Drive, this is for you. More specifically:

  • Developers looking for a minimal self-hosted file server (uploads, metadata, streaming, delete).
  • Anyone experimenting with cloud free tiers.
  • Folks who are at least comfortable with SSH, Git, and running a few Linux commands.

Prerequisites

Before you dive in, you’ll need:

  • The Spring Boot file-server boilerplate, download from Gumroad or Github. It includes a ready-to-go Postman collection.
  • A VPS or cloud account. Popular free options:
  • A local machine with ssh, scp, Java, and either Maven or Gradle.
  • A domain name. Not mandatory, but if you want HTTPS it makes life much easier.

⚠️ Free VPS tiers aren’t unlimited. Keep an eye on your usage so you don’t get billed.


What we’re setting up

The high-level picture looks like this:

  1. Spring Boot app listening on port 8000.
  2. Deployed either:
    • via systemd (native service), or
    • inside a Docker container.
  3. Nginx reverse proxy in front, handling SSL certificates from Let’s Encrypt.
  4. Files saved to local disk (you can later wire this up to object storage if needed).

Step 1: Prepare the boilerplate locally

Grab the boilerplate from Gumroad and open it in your favorite IDE.

Inside src/main/resources/application.properties, adjust it for your needs:

# Server
spring.application.name=springboot-file-upload-api
server.port=8000

# File config
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB

# Path to where files will be stored
upload.path=/opt/fileserver/uploads
Enter fullscreen mode Exit fullscreen mode

Now, test it locally with the provided Postman collection.
If things look good, package the JAR:

./mvnw clean package -DskipTests
Enter fullscreen mode Exit fullscreen mode

or

./gradlew bootJar
Enter fullscreen mode Exit fullscreen mode

You’ll find the JAR in target/file-server-0.1.0.jar.


Step 2: Grab a free VPS

Oracle Cloud’s free tier is generous and works well. AWS and GCP are also options, but their limits are tighter.
For this guide, I’ll assume you’re on Ubuntu 22.04. If you’re using another distro, the commands will be very similar.


Step 3: SSH into your server and prep it

ssh ubuntu@YOUR_VM_IP
Enter fullscreen mode Exit fullscreen mode

Update packages and install essentials:

sudo apt update && sudo apt upgrade -y
sudo apt install -y nginx certbot python3-certbot-nginx ufw \
    apt-transport-https ca-certificates curl software-properties-common
Enter fullscreen mode Exit fullscreen mode

Option A: Native deployment (systemd)

First, install Java:

sudo apt install -y openjdk-21-jdk
Enter fullscreen mode Exit fullscreen mode

Create a directory for your app:

sudo mkdir -p /opt/fileserver
Enter fullscreen mode Exit fullscreen mode

Upload your JAR:

scp target/file-server-0.1.0.jar ubuntu@YOUR_VM_IP:/opt/fileserver/app.jar
Enter fullscreen mode Exit fullscreen mode

Now create a systemd unit:

/etc/systemd/system/fileserver.service

[Unit]
Description=Spring Boot File Server
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/opt/fileserver
ExecStart=/usr/bin/java -jar /opt/fileserver/app.jar --spring.profiles.active=prod
Restart=always
RestartSec=10
Environment=JAVA_OPTS=-Xms256m -Xmx512m

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable fileserver
sudo systemctl start fileserver
sudo journalctl -u fileserver -f
Enter fullscreen mode Exit fullscreen mode

Option B: Docker deployment

Prefer containers? Install Docker:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo tee /usr/share/keyrings/docker-archive-keyring.gpg > /dev/null

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
  https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER
Enter fullscreen mode Exit fullscreen mode

⚠️ After adding your user to the docker group, log out and back in (or run newgrp docker).

Test it:

docker run hello-world
Enter fullscreen mode Exit fullscreen mode

Upload the JAR:

scp target/file-server-0.1.0.jar ubuntu@YOUR_VM_IP:/opt/fileserver/app.jar
Enter fullscreen mode Exit fullscreen mode

Create a Dockerfile in /opt/fileserver:

FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY app.jar app.jar
EXPOSE 8000
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Enter fullscreen mode Exit fullscreen mode

Build and run:

cd /opt/fileserver
docker build -t fileserver:latest .
docker run -d --name fileserver \
  -p 8000:8000 \
  -v /opt/fileserver/storage:/data \
  fileserver:latest
Enter fullscreen mode Exit fullscreen mode

Check logs:

docker logs -f fileserver
Enter fullscreen mode Exit fullscreen mode

Step 4: Put Nginx in front

Create a config at /etc/nginx/sites-available/fileserver:

server {
    listen 80;
    server_name fileserver.example.com;

    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable and reload:

sudo ln -s /etc/nginx/sites-available/fileserver /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Step 5: Add HTTPS

Run certbot:

sudo certbot --nginx -d fileserver.example.com
Enter fullscreen mode Exit fullscreen mode

Make sure auto-renewal is active:

systemctl status certbot.timer
Enter fullscreen mode Exit fullscreen mode

Step 6: Lock down with UFW

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
Enter fullscreen mode Exit fullscreen mode

Final notes & production tips

  • Storage → Local disk is fine, but for durability consider S3 or equivalent.
  • Monitoring → Use journalctl, docker logs, or hook up something like Prometheus.
  • Backups → Take snapshots or use rsync to back things up offsite.
  • Upload size → Tweak Nginx’s client_max_body_size if you plan on huge files.

🎉 Wrap-up

That’s it! You now have a fully working Spring Boot file server, running on a free VPS, accessible over HTTPS, and ready to test with Postman.

👉 Grab the boilerplate here:

🔗 More from BoilerAgents

If you found this boilerplate useful, you might also like:

Top comments (0)