Overall Flow #
- Set up the development environment
- Obtain source code and install dependent packages
- Verify operation on the development server
- Create a production build
- Configure nginx to serve built files
- HTTPS support (if necessary)
- Auto-start on restart (if necessary)
The following procedures provide specific work examples.
STEP1. Development Environment Setup #
STEP1.1 Install Node.js and npm #
On Ubuntu, install Node.js and npm with the following command.
sudo apt update
sudo apt install -y nodejs npm
After installation, verify the version.
node -v
npm -v
STEP1.2 Prepare the Server #
- Prepare a Linux server such as Ubuntu and ensure you can login via SSH.
- Prepare a user with root or sudo privileges (a prerequisite for production operation).
STEP2. Obtain Source Code #
STEP2.1 Download/Clone Source Code #
- If it is on GitHub, etc., obtain it with
git clone https://... - If it is a Zip file, upload and extract it
- The following assumes placement at
/home/project.
STEP2.2 Install Dependent Packages #
Navigate to the directory where the source code is located and install the required libraries with npm install.
cd /home/project
npm install
If successful, a node_modules directory will be generated.
STEP3. Verify Operation on Development Server #
During development, use npm run dev to launch a simple local server. The following is an example.
npm run dev
When executed, a log such as Local: http://localhost:5173 will appear in the terminal.
You can verify that the app is running by accessing that URL in your browser.
- If you want to test on a remote server, set
server.hostinvite.config.tsto0.0.0.0to make it accessible from outside.
STEP4. Create a Production Build #
When development stabilizes, create a production build. This process optimizes the app and generates
static files (HTML/JS/CSS) in the dist directory.
cd /home/project
npm run build
- If successful, a
distfolder will be generated at the project root. - It contains
index.htmland anassetsfolder, among others.
STEP5. Serve Built Files with nginx #
Rather than using Vite’s preview server, it is common to serve static files from a web server such as nginx.
STEP5.1 Install nginx #
Install nginx on Ubuntu.
sudo apt update
sudo apt install -y nginx
After installation, when you access http://<server IP address>/ in your browser,
the “Welcome to nginx!” page will be displayed.
STEP5.2 Place Production Files #
- Create a serving folder (example:
/var/www/myapp)sudo mkdir -p /var/www/myapp - Copy the built files (contents of
dist)sudo cp -r /home/project/dist/* /var/www/myapp/ - After placement, verify the contents
ls -l /var/www/myapp # OK if index.html and assets folder are present
STEP5.3 Create nginx Configuration File #
nginx manages configuration file server { ... } blocks
with sites-available/ → sites-enabled/ as the standard.
- Create a new configuration file
sudo nano /etc/nginx/sites-available/myapp.conf - Write the following content (example configuration for an SPA)
server { listen 80; server_name _; # For IP-only access. For a domain: server_name example.com; root /var/www/myapp; # dist file placement location index index.html; # SPA configuration: fallback to index.html even for router paths like /xxx location / { try_files $uri $uri/ /index.html; } }server_nameshould use the production domain for production, example:server_name example.com;root /var/www/myapp;specifies the directory where the built files are placedtry_files $uri $uri/ /index.html;is a configuration to fallback toindex.htmleven when directly accessing URLs if using React Router, etc.
- Enable the configuration file and disable the default configuration
# Place myapp.conf in sites-enabled with a symbolic link sudo ln -s /etc/nginx/sites-available/myapp.conf /etc/nginx/sites-enabled/ # Disable the default site if present sudo rm /etc/nginx/sites-enabled/default - Check nginx configuration file syntax & reload
sudo nginx -t sudo systemctl reload nginx - Access
http://<server IP>/in your browser- If the built app is displayed instead of the previous “Welcome to nginx!”, you are all set.
STEP6. Introduce HTTPS (SSL) (if necessary) #
Production environments typically support https://.
Example using free Let’s Encrypt (Certbot):
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
By proceeding through the interactive prompts, Certbot automatically incorporates SSL configuration into nginx, and you will be able to access via HTTPS.
(The DNS for yourdomain.com must point to this server.)
STEP7. Auto-start on Restart #
STEP7.1 For Static Files Only #
If nginx is serving the static files built by Vite,
there is generally no issue as long as nginx auto-starts. Verify that the following enablement is complete.
sudo systemctl enable nginx
This will ensure nginx starts automatically even when the server restarts.
STEP7.2 With Node.js + Express / API Server #
If a backend requires Node.js and you are running it on the same server, it is common to keep the Node.js process running with PM2 or systemd.
# Install PM2
sudo npm install -g pm2
# Start the app (Express, etc.)
pm2 start "npm run start" --name my-backend
# Enable auto-start
pm2 startup systemd
pm2 save
nginx would serve static files for the frontend and proxy_pass only requests to /api/ to Node.js,
creating a configuration like this.
STEP8. Troubleshooting #
- “Welcome to nginx!” page persists
- Default configuration has not been disabled
server_namedoes not match
- 404 error appears
- The
rootconfiguration path is incorrect try_filesis not configured for the SPA
- The
- Cannot access from browser
- Ports 80/443 are not open (cloud security groups or UFW)
- Server IP or domain name is not correctly assigned
STEP9. Summary #
- Development: Verify operation with
npm run dev - Build:
npm run build→ generatesdistfolder - Serve with nginx: Place contents of
distin/var/www/myapp→ configuremyapp.conf→nginx -t→systemctl reload nginx - HTTPS support: Obtain a certificate with
certbot --nginx -d yourdomain.com, etc. - Auto-start: For static files only, nginx will auto-start. For custom APIs as well, manage Node.js processes persistently with PM2 or systemd