Self-Hosting Taught Me That Deployment Is Part of Development
When I first thought about deploying an application, I mostly thought about getting the application onto a server.
Build the project.
Start the process.
Point the domain to it.
Done.
Running applications on my own VPS changed that perspective.
Deployment isn't the final step after development.
Deployment is another part of the system you are building.
My deployment stack is intentionally simple
For my self-hosted applications, I've worked with an Oracle Cloud Always Free VPS, Docker, Coolify, Traefik, MongoDB, HTTPS, and Linux server configuration.
The important thing isn't the specific tools.
It's the chain connecting them:
Internet
↓
Domain
↓
DNS
↓
VPS
↓
Traefik
↓
Docker container
↓
Application
↓
Database
`
When everything works, this feels invisible.
When something breaks, every layer matters.
A deployment is a system
Suppose my application isn't reachable.
There are many possible causes:
text
DNS problem
↓
Firewall problem
↓
Reverse proxy problem
↓
Container problem
↓
Application problem
↓
Database problem
If I only know how to start the application, I can still be completely stuck.
That's why self-hosting has been useful for learning.
It forces me to understand what happens outside the application code.
Reverse proxies are more than "configuration"
A reverse proxy sits between the public internet and the application.
Conceptually:
text
Client
↓
HTTPS
↓
Traefik
↓
Application container
It can handle things such as routing traffic to the correct service and terminating HTTPS.
This becomes especially useful when multiple applications need to run on the same server.
For example:
text
app.example.com
api.example.com
admin.example.com
can all point toward the same VPS while the reverse proxy decides where the traffic should go.
The application doesn't need to expose every service directly to the internet.
Containers solve one problem, not everything
Docker makes application deployment much more reproducible.
Instead of manually installing every dependency on the server, I can package the application environment into a container.
Conceptually:
text
Application
+
Dependencies
+
Runtime
↓
Container
But containers don't magically solve operational problems.
You still need to think about:
text
Logs
Storage
Networking
Environment variables
Backups
Updates
Security
Resource usage
A container can make deployment easier while still leaving you with a badly designed deployment.
Linux knowledge becomes practical very quickly
Self-hosting also made Linux commands much more useful to me.
Instead of learning commands only because they appear in tutorials, there is now a reason behind them.
For example:
bash
free -h
helps inspect memory.
bash
df -h
helps inspect disk usage.
bash
uptime
gives a quick view of system load and uptime.
And process/container logs can tell you what the application is actually doing.
The important skill isn't memorizing commands.
It's knowing which question each command helps answer.
Monitoring changes how you think
A server can be "working" while slowly heading toward a problem.
For example:
text
Disk usage increasing
↓
Logs accumulate
↓
Available storage decreases
↓
Eventually something fails
The application might appear perfectly healthy until the moment it isn't.
This is why monitoring resources such as:
text
CPU
RAM
Disk
Network
Container health
Application logs
matters even for small projects.
You don't need a massive observability platform to start paying attention.
The uncomfortable part of self-hosting
Self-hosting gives you control.
It also gives you responsibility.
If you use a managed platform, many infrastructure problems are someone else's responsibility.
On your own VPS, they aren't.
You become responsible for understanding:
text
Updates
Security
Firewall rules
Backups
SSL
Resource limits
Database availability
Application failures
That's not a downside if your goal is to learn infrastructure.
But pretending self-hosting is just "free hosting" misses the point.
The infrastructure becomes your problem.
The lesson
The biggest thing I have learned from deploying my own applications is that the code is only one part of the product.
A working application needs:
text
Code
+
Database
+
Networking
+
Infrastructure
+
Security
+
Deployment
+
Monitoring
You don't need to master all of these before deploying your first project.
But you should understand enough of each layer to troubleshoot when something inevitably goes wrong.
That's what makes deployment engineering rather than simply uploading a project to a server.
The moment your application is running on a real machine connected to the internet, infrastructure becomes part of your codebase—even if it isn't written in your programming language.
Top comments (0)