Deploying a Vue.js + FastAPI application on Linux with Nginx
Common mistakes and how to fix them

Software Developer I build modern SaaS tools with Vue.js & FastAPI · Sharing tutorials, dev logs, and business insights for solo devs & makers. Building in public.
Introduction
Deploying a full-stack application often looks simple on paper: a frontend, a backend, and a web server in between. In reality, deployment is where many hidden problems appear.
In this article, I share my real-world experience deploying a Vue.js frontend and a FastAPI backend on a Linux server using Nginx, along with the most common mistakes I encountered and how I fixed them.
This article is practical, experience-based, and aimed at developers who want to avoid losing hours (or days) during deployment.
1. Project architecture
Here is the architecture used:
Frontend: Vue.js (built with
npm run build)Backend: FastAPI (served with Uvicorn / Gunicorn)
Web server: Nginx
Protocol: HTTPS
Directory structure on the server:
/var/www/frontend/dist→ Vue.js build/var/www/api→ FastAPI application
Nginx acts as:
Static file server for the frontend
Reverse proxy for the FastAPI backend
2. Basic Nginx configuration
A minimal and working Nginx configuration looks like this:
server {
server_name example.com;
# Frontend (Vue.js)
location / {
root /var/www/frontend/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
# Backend (FastAPI)
location /api/ {
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
At this stage, everything looks correct — but this is where problems usually begin.
3. Common mistake #1: "It works in local, but not in production"
This is probably the most common deployment issue.
Cause
Local environment ≠ production environment
Different ports
Different domains
Missing HTTPS
Solution
Always test with production-like variables
Use environment variables for API URLs
Example in Vue:
VITE_API_BASE_URL=https://example.com/api
4. Common mistake #2: Mixed Content (HTTPS frontend, HTTP API)
Error
The browser blocks API calls because:
Frontend is served over HTTPS
Backend is called over HTTP
Solution
Always call the API through Nginx, not directly.
❌ Wrong:
http://server-ip:8000
✅ Correct:
https://example.com/api
Nginx handles HTTPS → HTTP internally.
5. Common mistake #3: CORS errors
Cause
Calling the API directly instead of through the reverse proxy.
Solution
Use Nginx as the single entry point
Keep frontend and backend under the same domain
FastAPI CORS should be a backup, not the main solution.
6. Common mistake #4: API routes not found
Cause
Missing or incorrect /api prefix in proxy_pass.
Rule to remember
/api/inlocation/at the end ofproxy_pass
7. Running FastAPI properly in production
Avoid using uvicorn --reload in production.
Recommended:
Gunicorn + Uvicorn workers
Systemd service
Example:
gunicorn -k uvicorn.workers.UvicornWorker app.main:app
8. Lessons learned
Deployment is part of development
Nginx is a powerful tool, not just a server
HTTPS and reverse proxying must be understood early
Debugging deployment issues improves architecture skills
Conclusion
If your application works only in local, it is not finished.
Understanding deployment forces you to think like a software engineer, not just a coder. Vue.js, FastAPI, and Nginx work extremely well together — once properly configured.



