Skip to main content

NGINX Deployment

This guide covers deploying your Docusaurus site using NGINX as a web server. NGINX is a high-performance web server that can serve your static files efficiently and handle reverse proxying if needed.

Prerequisites

Before you begin, make sure you have:

  • A Docusaurus project built for production (npm run build or equivalent)
  • NGINX installed on your server
  • Basic knowledge of NGINX configuration

Basic Static File Serving

Building Your Site

First, build your Docusaurus site for production:

npm run build

This generates static files in the build/ directory by default.

NGINX Configuration

Create an NGINX configuration file (e.g., /etc/nginx/sites-available/docusaurus):

server {
listen 80;
server_name your-domain.com;
root /var/www/docusaurus/build;
index index.html;

# Serve static files directly
location / {
try_files $uri $uri/ /index.html;
}

# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

# Disable access log for static files
location ~* \.(js|css)$ {
access_log off;
}
}

Enabling the Site

# Create symlink to enable the site
sudo ln -s /etc/nginx/sites-available/docusaurus /etc/nginx/sites-enabled/

# Test NGINX configuration
sudo nginx -t

# Restart NGINX
sudo systemctl restart nginx

Docker + NGINX

Dockerfile

Create a Dockerfile in your project root:

# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json yarn.lock ./
RUN corepack enable && yarn install --frozen-lockfile
COPY . .
RUN yarn build

# Stage 2: Serve with NGINX
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

NGINX Configuration for Docker

Create nginx.conf in your project root:

server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

Building and Running

# Build the Docker image
docker build -t docusaurus-nginx .

# Run the container
docker run -d -p 80:80 --name docusaurus docusaurus-nginx

Docker Compose

Create a docker-compose.yml:

version: '3.8'

services:
docusaurus:
build: .
ports:
- "80:80"
restart: unless-stopped

Run with:

docker-compose up -d

SSL/TLS with Let's Encrypt

Using Certbot

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Get and install certificate
sudo certbot --nginx -d your-domain.com

# Auto-renewal is set up automatically
# Test renewal
sudo certbot renew --dry-run

Updated NGINX Configuration with SSL

server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name your-domain.com;
root /var/www/docusaurus/build;
index index.html;

ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
try_files $uri $uri/ /index.html;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

Reverse Proxy Setup

If you're running Docusaurus development server or a custom backend:

server {
listen 80;
server_name your-domain.com;

# Serve static files
location / {
root /var/www/docusaurus/build;
try_files $uri $uri/ /index.html;
}

# Proxy to development server (for hot reload)
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Troubleshooting

404 Errors on Page Refresh

This is the most common issue with SPAs. Make sure you have:

location / {
try_files $uri $uri/ /index.html;
}

CORS Issues

If you're serving from a subdirectory:

location /subdir/ {
alias /var/www/docusaurus/build/;
try_files $uri $uri/ /subdir/index.html;
}

Permission Issues

# Set correct permissions
sudo chown -R www-data:www-data /var/www/docusaurus
sudo chmod -R 755 /var/www/docusaurus

Check NGINX Logs

# Error log
sudo tail -f /var/log/nginx/error.log

# Access log
sudo tail -f /var/log/nginx/access.log

Performance Tips

  1. Enable Gzip Compression:
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
  1. Enable Brotli Compression (if compiled with Brotli module):
brotli on;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml;
  1. Use Open File Cache:
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

Further Reading