Back to Home

🌐 Networking Basics

Learn networking concepts for self-hosted applications

Understanding Ports & Forwarding

Ports are communication endpoints on your server. Each service uses a specific port number to accept connections.

Port Mapping Diagram

Internet
Router
:80 → :8080
Container

Common Port Numbers

80 HTTP (Web)
443 HTTPS (Secure Web)
22 SSH
21 FTP
25 SMTP (Email)
3306 MySQL
5432 PostgreSQL
6379 Redis

Docker Networking

Bridge Network (Default)

# Run container with port mapping docker run -d -p 8080:80 nginx # Syntax: -p host_port:container_port # Example: -p 3000:3000 maps host port 3000 to container port 3000

Network Types

bridge Default network, containers can communicate
host Removes network isolation
overlay Multi-host Docker networks
none Disables all networking

Create Custom Network

# Create a custom bridge network docker network create mynetwork # Run container on custom network docker run --network mynetwork -d nginx # Connect existing container to network docker network connect mynetwork container_name # List networks docker network ls # Inspect network docker network inspect mynetwork

UFW Firewall (Ubuntu)

UFW (Uncomplicated Firewall) makes managing iptables rules easy.

Basic Commands

# Enable firewall sudo ufw enable # Disable firewall sudo ufw disable # Check status sudo ufw status verbose # Allow SSH sudo ufw allow ssh sudo ufw allow 22/tcp # Allow HTTP/HTTPS sudo ufw allow http sudo ufw allow 80/tcp sudo ufw allow https sudo ufw allow 443/tcp # Allow specific port sudo ufw allow 3000/tcp # Deny incoming by default sudo ufw default deny incoming # Allow outgoing by default sudo ufw default allow outgoing

Port Ranges

# Allow range of ports sudo ufw allow 8000:9000/tcp # Delete rule sudo ufw delete allow 3000/tcp # List numbered rules sudo ufw status numbered
⚠️ Warning: Always allow SSH (port 22) before enabling the firewall, or you may lock yourself out of your server!

Reverse Proxy with Nginx

A reverse proxy forwards client requests to backend servers and returns responses.

Basic Nginx Reverse Proxy Config

server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; 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; proxy_cache_bypass $http_upgrade; } }

Docker + Nginx Reverse Proxy

# Run nginx as reverse proxy docker run -d \ --name nginx-proxy \ -p 80:80 \ -p 443:443 \ -v /var/run/docker.sock:/tmp/docker.sock:ro \ nginx

Dynamic DNS (DDNS)

DDNS automatically updates DNS records when your IP address changes.

Using DDNS with a Script

# Install ddclient sudo apt install ddclient # Configure ddclient sudo nano /etc/ddclient.conf # Example configuration for No-IP protocol=noip use=web serverlogin=your-email@example.com password=your-password your-hostname.ddns.net

Cloudflare DDNS Script

#!/bin/bash # Cloudflare DDNS update script ZONE_ID=your_zone_id RECORD_ID=your_record_id EMAIL=your_email@example.com API_KEY=your_api_key DOMAIN=example.com IP=$(curl -s https://api.ipify.org) curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \ -H "X-Auth-Email: $EMAIL" \ -H "X-Auth-Key: $API_KEY" \ -H "Content-Type: application/json" \ --data '{"type":"A","name":"'"$DOMAIN"'","content":"'"$IP"'"}'

SSL/HTTPS with Let's Encrypt

Install Certbot

sudo apt update sudo apt install certbot python3-certbot-nginx

Get SSL Certificate

# For Nginx sudo certbot --nginx -d example.com -d www.example.com # For Apache sudo certbot --apache -d example.com -d www.example.com # Standalone (if no web server running) sudo certbot certonly --standalone -d example.com

Auto-Renewal

# Test automatic renewal sudo certbot renew --dry-run # Check renewal status sudo certbot renew
💡 Note: Let's Encrypt certificates expire after 90 days. Certbot sets up automatic renewal by default.

Docker Compose with Networking

version: '3.8' services: nginx: image: nginx:latest" ports: - "80:80" - "443:443" networks: - frontend volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro app: build: . networks: - frontend - backend database: image: postgres:14" networks: - backend volumes: - db-data:/var/lib/postgresql/data networks: frontend: backend: volumes: db-data:

Network Troubleshooting

ping [host] Test connectivity
traceroute [host] Trace route to host
netstat -tulpn Show listening ports
ss -tulpn Socket statistics
curl -v [url] Test HTTP request
nslookup [domain] DNS lookup
dig [domain] Detailed DNS info
ip addr show Show network interfaces
iptables -L List firewall rules

Docker Network Troubleshooting

# Inspect container network docker inspect container_name # View container logs docker logs container_name # Execute command in container docker exec -it container_name sh # Test network from container docker exec container_name ping other_container # Check DNS resolution docker exec container_name nslookup google.com

Security Best Practices

✅ Always:
  • Use HTTPS/SSL for all web services
  • Keep software updated
  • Use strong passwords and SSH keys
  • Configure firewall rules properly
  • Limit exposed ports
  • Use reverse proxies
❌ Never:
  • Expose databases directly to the internet
  • Use default ports for services
  • Run containers as root when possible
  • Disable firewall for "convenience"