Skip to content

lue93/setup-nginx-behind-tailscale

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 

Repository files navigation

πŸš€ Setup Nginx Behind Tailscale

Securely expose your Nginx web server using the power of Tailscale β€” a zero-config VPN built on WireGuard. This guide walks you through:

  • πŸ” Configuring HTTPS with Tailscale-generated certificates
  • 🌐 Mapping host ports to your containerized Nginx instance
  • πŸ›‘οΈ Restricting access to your private tailnet only

Whether you're self-hosting a dashboard, API, or static site, this setup ensures encrypted, authenticated access across your trusted devices β€” without opening public ports.

πŸ“¦ Built for Docker environments.
🧩 Compatible with Alpine-based Nginx images.
🧠 Designed for simplicity and security.

Run these commands to create the folder where Nginx will live.

mkdir proxy
cd proxy

Run these commands to creates folder structure

mkdir /html
mkdir -p /etc/nginx/conf.d
mkdir -p /etc/ssl/certs

Go to certs folder

cd /etc/ssl/certs

Run tailscale command to generate ssl certificate for your domain machine

sudo tailscale cert machineName.tailID.ts.net

At Below files, you need replace this domain for your domain's : machineName.tailID.ts.net

This is the docker compose file that creates a nginx container, save it inside proxy folder. /proxy/docker-compose.yml

version: "3.9"

networks:
  nginx-net:
    driver: bridge

services:
  nginx:
    image: nginx:stable-alpine3.21
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html/index.html:/usr/share/nginx/html/index.html
      - ./etc/nginx/conf.d:/etc/nginx/conf.d
      - ./etc/nginx/default.conf:/etc/nginx/default.conf
      - ./etc/ssl/certs:/etc/ssl/certs

Put this file at /etc/nginx/default.conf

user  nginx;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout 65;

    # Zonas de limite (opcional)
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;

    # Tamanho do nome de dominio
    server_names_hash_bucket_size 256;

    # Incluir sites
    include /conf.d/*.conf;

}

Put this file at /etc/nginx/conf.d/default.conf

server {
    listen 80;
    server_name machineName.tailID.ts.net;
    
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ =404;
    }

}
server {
    listen 443 ssl;
    server_name machineName.tailID.ts.net;

    # Setup valid tls versions
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'HIGH:!aNULL:!MD5';
    ssl_prefer_server_ciphers off;


    ## Access and error logs.
    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log info;

    ## Keep alive timeout set to a greater value for SSL/TLS.
    keepalive_timeout 75 75;


    ssl_certificate     /etc/ssl/certs/machineName.tailID.ts.net.crt;
    ssl_certificate_key /etc/ssl/certs/machineName.tailID.ts.net.key;
    ssl_session_timeout  5m;

    ## Strict Transport Security header for enhanced security. See
    ## http://www.chromium.org/sts. I've set it to 2 hours; set it to
    ## whichever age you want.
    add_header Strict-Transport-Security "max-age=7200";


    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ =404;
    }

    
}

At proxy folder's

sudo tailscale up
docker compose up -d
curl -vk machineName.tailID.ts.net

πŸ’– Sponsor Us πŸ’–

If you found this documentation useful, please consider supporting our work by becoming a sponsor.

Releases

No releases published

Packages

No packages published