Multi-Domain: Hosting a Vue Frontend and Laravel Backend with Nginx
Copy linkUpdating the Package List in Ubuntu
Before installing any new software, it's essential to update the package list to ensure you get the latest available versions. Open a terminal and run the following command:
sudo apt update
This command fetches the latest package information from the configured repositories, ensuring that your system is aware of the newest updates and available software versions.After updating, you can proceed with installing new software packages with confidence.
To install Nginx on Ubuntu, follow these steps:
Install Nginx
Once the package list is updated, install Nginx using the following command:
sudo apt install nginx
This command downloads and installs Nginx along with its necessary dependencies.
Start and Enable Nginx
After installation, start the Nginx service to begin serving web pages
sudo systemctl start nginx
To ensure that Nginx starts automatically on system boot, enable it using:
sudo systemctl enable nginx
Check Nginx Status
To confirm that Nginx is running without issues, check its status:
sudo systemctl status nginx
If the installation was successful, you should see an output indicating that the service is active and running.
Verify Installation
To verify that Nginx is correctly installed and running, open a web browser and visit:
http://your-server-ip
Replace your-server-ip
with your actual server's IP address. If Nginx is working correctly, you will see the default "Welcome to Nginx" page.
Installing and Verifying PHP 8.3 with PHP-FPM on Ubuntu
Install PHP 8.3 and PHP-FPM
To install PHP 8.3 and PHP-FPM (FastCGI Process Manager), run the following command:
sudo apt install php8.3 php8.3-fpm
php8.3
→ Installs PHP 8.3, which is required for running PHP applications.php8.3-fpm
→ Installs PHP-FPM, which is needed for handling PHP requests in an efficient way, especially when using Nginx as the web server.
Verify PHP Installation
To check if PHP 8.3 is installed correctly, run:
php –v
This will output something like:
PHP 8.3.x (cli) (built: Jan 24 2025 14:35:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.3.0, Copyright (c) Zend Technologies
This confirms that PHP 8.3 is installed and working.
Start and Enable PHP-FPM
After installation, PHP-FPM might not start automatically. To manually start it, run:
sudo systemctl start php8.3-fpm
To ensure PHP-FPM starts automatically on system boot, enable it with:
sudo systemctl enable php8.3-fpm
This ensures that PHP-FPM runs automatically after every reboot.
Check PHP-FPM Status
To verify that PHP-FPM is running correctly, use:
sudo systemctl status php8.3-fpm
You should see output similar to:
● php8.3-fpm.service - The PHP 8.3 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.3-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2025-02-04 12:15:34 UTC; 2min ago
If the status shows active (running), it means PHP-FPM is successfully running and ready to handle PHP requests.
Creating and Activating a New Nginx Server Block
Copy the Default Server Block
Run the following command to duplicate the default configuration file:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com
If you have two domains, you need to copy the default Nginx configuration file twice, creating separate server block files for each domain. This ensures that each domain has its own unique configuration and root directory.
Each copied file must be edited to specify the correct server_name
and logging paths for the respective domain.
Edit the New Server Block
Open the new file for editing:
sudo nano /etc/nginx/sites-available/example.com
Updated Server Block
In an Nginx configuration, the server block is responsible for handling requests and routing them to the appropriate content. When you have a server block that needs to handle an API and static content (e.g., Vue.js frontend), it will include a mix of configurations for both.
server {
listen 80;
server_name example.com www.example.com;
root /var/www/html/vue-frontend;
index index.html;
# Log files for access and errors
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
location /api/ {
root /var/www/html/larvel-backend/public;
fastcgi_param HTTP_CLIENT_KEY $http_client_key;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; # Ensure this matches your PHP version
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param HTTP_CLIENT_KEY "HOYO_TECH";
}
# Serve Vue static files correctly
location / {
include /etc/nginx/mime.types;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
try_files $uri $uri/ /index.html;
}
# Handle 404 errors by redirecting to Vue index.html (for history mode)
error_page 404 /index.html;
}
Explanation of Key Parts of the Server Block:
1. listen
Directive
listen 80;
- Purpose: This directive tells Nginx to listen for incoming HTTP requests on port 80, the default port for HTTP traffic.
- Explanation: When a client (like a browser) makes a request to a server, this
listen
directive specifies the port Nginx will listen to for that request. Port 80 is the standard for unsecured HTTP traffic, and Nginx will respond to requests that come in on this port.
2. API Block (location /api/
)
location /api/ {
root /var/www/html/larvel-backend/public;
fastcgi_param HTTP_CLIENT_KEY $http_client_key;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock; # Ensure this matches your PHP version
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param HTTP_CLIENT_KEY "HOYO_TECH";
}
- Purpose: This block handles requests that start with
/api/
and passes them to PHP-FPM for processing (typically for an API backend written in PHP, like Laravel or another CMS). - Explanation:
- 1.
location /api/
: This means any request that begins with/api/
will be routed to this block. For example, requests toexample.com/api/users
would be routed here. - 2.
root /var/www/html/larvel-backend/public;
: Sets the base directory for the API - 3.
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
: This passes the request to PHP-FPM via a Unix socket. PHP-FPM is used to process PHP scripts. Ensure the version of PHP-FPM matches the installed version (e.g.,php8.3-fpm.sock
). - 4.
fastcgi_param
directives: These set up parameters needed for PHP to process the request, such as the script file to execute (SCRIPT_FILENAME
), the request method (REQUEST_METHOD
), and custom headers likeHTTP_CLIENT_KEY
. These ensure that PHP handles the request properly. - 5. The value of
HTTP_CLIENT_KEY
is different for each domain (i.e., each server block), so it allows the backend to serve different data based on the key. - 6. The
HTTP_CLIENT_KEY
header is set uniquely for each server block (domain).
- 1.
3. Vue Static Files Block (location /
)
location / {
include /etc/nginx/mime.types;
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
try_files $uri $uri/ /index.html;
}
- Purpose: This block serves the static files for the Vue.js frontend application, which includes HTML, JavaScript, CSS, etc. It also ensures that the Vue app works correctly with client-side routing (such as when using Vue Router in history mode).
- Explanation
- 1.
location /
: This block matches requests to the root and any subdirectories that do not match the/api/
path (i.e., requests for static assets or frontend pages). - 2.
try_files $uri $uri/ /index.html;
: This directive tells Nginx to try to serve the requested file ($uri
) first. If it doesn't exist, it tries the directory ($uri/
). If neither exists, it serves theindex.html
file. This ensures that Vue's client-side routing works, and any route that doesn’t match a file is routed toindex.html
for Vue to handle. - 3.
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
: Disables caching for the frontend assets, ensuring that the latest versions of files are served during development. - 4.
expires off; etag off;
: These further prevent caching of the static files. - 5.
include /etc/nginx/mime.types;
: This includes MIME type definitions to ensure that Nginx serves the correct content types for various static assets (like.js
,.css
, etc.).
- 1.
Enable the New Server Block
Create a symbolic link to activate the site:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Test the Configuration
Check for syntax errors:
sudo nginx -t
If successful, restart Nginx:
sudo systemctl restart nginx
Test in a Browser
Visit:
http://example.com
Your new Nginx block is now active!
In Summary:
This configuration is meant for a multi-domain setup where:
- Each domain (
example.com
andanother-domain.com
) can have its own custom behavior for API requests. - The backend can differentiate between requests from the different domains based on the injected
HTTP_CLIENT_KEY
header, allowing for tailored responses or data. - It also serves the same Vue.js frontend (static files) for both domains but handles API requests differently based on the domain-specific
HTTP_CLIENT_KEY
.
Milosh Stankovikj
iOS Developer
Feb 06, 2025