Port 443 — HTTPS
Every time you see a padlock icon in your browser's address bar, you're using port 443. It's the default port for HTTPS — the encrypted version of HTTP that protects everything from banking logins to social media scrolling. If port 80 is the front door, port 443 is the front door with a deadbolt, a camera, and an armed guard. In 2026, essentially every major website uses HTTPS, and browsers actively warn users when a site doesn't.
For web developers, port 443 matters in two contexts: configuring it on production servers, and setting up local HTTPS for development when your app requires it.
How HTTPS and Port 443 Actually Work
When you type https://example.com in your browser, here's what happens before a single byte of web content is transferred:
- Your browser connects to the server on port 443 (this is implicit — you don't type the port because 443 is the default for https://)
- The server sends its SSL/TLS certificate — a file that proves "I am really example.com" and contains a public encryption key
- Your browser verifies the certificate against a list of trusted Certificate Authorities (CAs) built into your OS and browser
- Browser and server perform a TLS handshake — agreeing on an encryption method and generating a shared secret key
- All subsequent traffic is encrypted with that key — even your ISP can't read it
This whole process takes about 50-100ms. The "S" in HTTPS stands for "Secure" — technically it's HTTP running inside a TLS (Transport Layer Security) tunnel.
Setting Up HTTPS on a Production Server
Let's Encrypt (Free SSL Certificates)
Let's Encrypt provides free SSL certificates that are trusted by all browsers. With Certbot, you can set up HTTPS in about 2 minutes:
# Ubuntu/Debian with Nginx
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Ubuntu/Debian with Apache
sudo apt install certbot python3-certbot-apache
sudo certbot --apache -d yourdomain.com
# Auto-renewal (Certbot adds this automatically)
sudo certbot renew --dry-run
Let's Encrypt certificates expire every 90 days, but Certbot handles automatic renewal. It's what most websites use today — there's rarely a reason to pay for SSL certificates anymore.
Nginx HTTPS Configuration
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# Modern TLS settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.html;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
Apache HTTPS Configuration
<VirtualHost *:443>
ServerName yourdomain.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
</VirtualHost>
# Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName yourdomain.com
Redirect permanent / https://yourdomain.com/
</VirtualHost>
Local HTTPS for Development
Some features require HTTPS even in development — service workers, geolocation, camera/microphone access, and some third-party APIs. You can't just use http://localhost for these. The easiest solution is mkcert:
# Install mkcert
# macOS
brew install mkcert
# Linux
sudo apt install libnss3-tools
# Then download from github.com/FiloSottile/mkcert
# Windows (Chocolatey)
choco install mkcert
# Create a local CA (one-time setup)
mkcert -install
# Generate certificates for localhost
mkcert localhost 127.0.0.1 ::1
# This creates:
# localhost+2.pem (certificate)
# localhost+2-key.pem (private key)
mkcert creates a local Certificate Authority on your machine and issues certificates signed by it. Your browser trusts the CA, so https://localhost works without security warnings. No self-signed certificate hacks needed.
Using the Certificates
# Node.js / Express
const https = require('https');
const fs = require('fs');
const express = require('express');
const app = express();
https.createServer({
key: fs.readFileSync('localhost+2-key.pem'),
cert: fs.readFileSync('localhost+2.pem')
}, app).listen(443);
# Vite (vite.config.js)
import fs from 'fs';
export default {
server: {
https: {
key: fs.readFileSync('localhost+2-key.pem'),
cert: fs.readFileSync('localhost+2.pem'),
}
}
}
# Nginx (local)
ssl_certificate /path/to/localhost+2.pem;
ssl_certificate_key /path/to/localhost+2-key.pem;
Port 443 vs Port 80
| Port 80 (HTTP) | Port 443 (HTTPS) | |
|---|---|---|
| Encryption | None — traffic is plaintext | TLS encryption |
| Certificate required | No | Yes |
| Browser behavior | "Not Secure" warning | Padlock icon |
| SEO impact | Google penalizes HTTP-only sites | Ranking boost |
| Required for | Nothing (legacy only) | Service workers, PWAs, geolocation, camera, HTTP/2 |
In 2026, there's virtually no reason to serve a production website on port 80 except as a redirect to port 443.
Troubleshooting
"Your connection is not private" on localhost: Your browser doesn't trust the certificate. Use mkcert (above) to create a properly trusted local cert instead of a self-signed one. Or in Chrome, type thisisunsafe on the warning page to bypass it temporarily.
Port 443 requires root/admin: On Linux and macOS, ports below 1024 require root privileges. Either run your server with sudo, use a reverse proxy like Nginx on 443 that forwards to your app on a higher port, or use setcap on Linux to grant the specific binary permission.
Mixed content warnings: If your page loads over HTTPS but includes resources (images, scripts, CSS) over HTTP, the browser blocks or warns about them. Ensure all URLs use https:// or protocol-relative // paths.