Explore plans starting at ₹699/mo →
VPS & Servers

How to Set Up a Production Web Server

S
ServerRaja
11 min read
#Infrastructure#Linux#Web Server#Nginx#Security#Best Practices
How to Set Up a Production Web Server

Setting up a production web server requires attention to security, performance, reliability, and maintainability. This guide walks through a complete production server configuration from initial setup to ongoing operations.

Operating System Preparation

Start with a minimal server installation and update all packages:

Ubuntu: sudo apt update && sudo apt upgrade -y CentOS: sudo dnf update -y

Create a non-root administrative user: sudo adduser deploy sudo usermod -aG sudo deploy

Configure SSH key authentication and disable password authentication (see the Linux VPS security guide for detailed SSH hardening steps).

Firewall Configuration

Configure the firewall to allow only necessary traffic:

Using UFW: sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow http sudo ufw allow https sudo ufw enable

If your application needs database access from external hosts, add the database port to the allow list. Prefer SSH tunnels or private networking for database connections.

Nginx Installation and Configuration

Install Nginx: sudo apt install nginx (Ubuntu) sudo dnf install nginx (CentOS)

Create a virtual host configuration for your domain:

server { listen 80; server_name yourdomain.com www.yourdomain.com; return 301 https://$host$request_uri; }

server { listen 443 ssl http2; server_name yourdomain.com www.yourdomain.com;

ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

root /var/www/yourdomain.com/public; index index.html;

location / { try_files $uri $uri/ @backend; }

location @backend { proxy_pass http://127.0.0.1:3000; 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; } }

This configuration: - Redirects HTTP to HTTPS - Serves static files directly from Nginx (fast) - Proxies dynamic requests to the application backend - Passes client IP information to the application

TLS Certificate Setup

Install Certbot for Let's Encrypt certificates: sudo apt install certbot python3-certbot-nginx

Obtain a certificate: sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot automatically configures Nginx for HTTPS and sets up automatic certificate renewal.

Application Process Management

Your application needs to run as a managed service that starts automatically and restarts on failure.

Using systemd

Create a service unit file /etc/systemd/system/yourapp.service:

[Unit] Description=Your Application After=network.target

[Service] Type=simple User=deploy WorkingDirectory=/var/www/yourdomain.com ExecStart=/usr/bin/node server.js Restart=always RestartSec=5 Environment=NODE_ENV=production

[Install] WantedBy=multi-user.target

Enable and start: sudo systemctl enable yourapp sudo systemctl start yourapp

The Restart=always directive ensures the application restarts automatically if it crashes.

Using PM2 (for Node.js)

PM2 is a process manager specifically designed for Node.js applications: npm install -g pm2 pm2 start server.js --name yourapp pm2 startup (generates startup script) pm2 save

Database Configuration

If running a database on the same server:

Install PostgreSQL: sudo apt install postgresql postgresql-contrib

Configure for production: - Set appropriate shared_buffers (25% of system RAM) - Configure effective_cache_size (75% of system RAM) - Set work_mem based on concurrent query patterns - Enable connection pooling (pgbouncer) for high-traffic applications

For better isolation, consider running the database on a separate server.

Logging

Configure structured logging for all components:

Nginx logs: access and error logs in /var/log/nginx/ Application logs: use structured JSON format for machine parsing System logs: configure journald for persistent storage

Implement log rotation to prevent disk space exhaustion. The logrotate utility handles this automatically for most services.

Backups

Configure automated backups:

Database backups: pg_dump for PostgreSQL, mysqldump for MySQL File backups: rsync to an external location Configuration backups: version control your server configuration files

Store backups off-server and test restoration procedures regularly.

Monitoring

Set up monitoring for: - Server resources (CPU, RAM, disk, network) - Application health (response time, error rate) - TLS certificate expiry - Disk space trends - Backup success/failure

Configure alerts for critical thresholds. Alerts should reach someone who can act on them.

Security Hardening

Beyond the basics covered above: - Set appropriate HTTP security headers (Content-Security-Policy, X-Frame-Options, etc.) - Configure rate limiting in Nginx for API endpoints - Keep all software updated with security patches - Review access logs for suspicious patterns - Implement fail2ban for brute-force protection

Performance Optimization

  • Enable gzip compression in Nginx for text-based responses
  • Configure browser caching headers for static assets
  • Use a CDN for static content delivery
  • Optimize application-level caching (database query cache, HTTP cache headers)
  • Monitor and tune database query performance

Conclusion

A production web server is more than just installing Nginx. Security, monitoring, backups, logging, and process management are equally important for reliable operations. Start with these fundamentals and iterate based on your application's specific requirements.

Production Web Server Setup Guide | ServerRaja