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:
- Spring Boot app listening on port 8000.
- Deployed either:
- via systemd (native service), or
- inside a Docker container.
- Nginx reverse proxy in front, handling SSL certificates from Let’s Encrypt.
- 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
Now, test it locally with the provided Postman collection.
If things look good, package the JAR:
./mvnw clean package -DskipTests
or
./gradlew bootJar
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
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
Option A: Native deployment (systemd)
First, install Java:
sudo apt install -y openjdk-21-jdk
Create a directory for your app:
sudo mkdir -p /opt/fileserver
Upload your JAR:
scp target/file-server-0.1.0.jar ubuntu@YOUR_VM_IP:/opt/fileserver/app.jar
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
Enable and start it:
sudo systemctl daemon-reload
sudo systemctl enable fileserver
sudo systemctl start fileserver
sudo journalctl -u fileserver -f
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
⚠️ After adding your user to the docker group, log out and back in (or run
newgrp docker
).
Test it:
docker run hello-world
Upload the JAR:
scp target/file-server-0.1.0.jar ubuntu@YOUR_VM_IP:/opt/fileserver/app.jar
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"]
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
Check logs:
docker logs -f fileserver
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;
}
}
Enable and reload:
sudo ln -s /etc/nginx/sites-available/fileserver /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 5: Add HTTPS
Run certbot:
sudo certbot --nginx -d fileserver.example.com
Make sure auto-renewal is active:
systemctl status certbot.timer
Step 6: Lock down with UFW
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
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:
- AuthKit — Spring Boot JWT Authentication Boilerplate Secure login, refresh tokens, and role-based access in minutes. --- 👉 Subscribe to get updates on new boilerplates, free resources, and practical tips — https://boileragent.gumroad.com/
Top comments (0)