Skip to main content

Docker, Nginx & Linux Stack Visual Composer

Visually compose production container stacks: select Nginx/Cloudflare ingress, frontend, backend API, databases & Redis. Generates SVG topology, docker-compose.yml, and UFW scripts.

Input Parameters

Try Example:
165535

Calculation Results

Stack Project Name
kampus-app
Production Target Domain
app.example.com
Total Active Containers
7 Containers
Estimated RAM Memory Usage
1872 MB
Recommended VPS Specification
4 vCPU / 4 GB RAM
Security Posture & Isolation
ZERO-TRUST TUNNEL (0 Port Web Terbuka di IP Publik + DB Terisolasi)
Want to compare 2 design options side-by-side (e.g., Scenario A vs Scenario B)?
🐳Open Full Visual Lego Stack Composer Studio
Visually compose containers with interactive SVG network topology diagram and HD PNG export.
Open Lego Studio šŸš€
⚔ Production Security & Ops Standard
Debian 12 / Ubuntu 24.04 LTS + Nftables + Systemd Timer
CIS Benchmark Level 1 • Non-Root SSH Key-Only + Fail2ban/CrowdSec

Validate firewall rulesets and cron timers in staging before production rollout.

Container Services & Port Architecture Table
Container Service NameService RoleDocker Image BaseContainer Internal PortPublic WAN ExposureEstimated RAM
nginx-proxyEdge Reverse Proxy & SSL Terminationnginx:1.27-alpine80, 443127.0.0.1:8080 (Local/Tunnel)96 MB
cloudflaredZero-Trust Outbound Tunnel (Zero Open Inbound Port)cloudflare/cloudflared:latestOutbound QUIC/HTTP2TERTUTUP (0 Port Terbuka di IP Publik VPS)80 MB
frontendNext.js SSR Frontendnode:20-alpine3000/tcpInternal Only (stack-net)384 MB
backend-apiLaravel PHP 8.3 (Octane/FrankenPHP)dunglas/frankenphp:1-php8.3-alpine8000/tcpInternal Only (stack-net)512 MB
databasePostgreSQL 16 Relational DBpostgres:16-alpine5432/tcpTerisolasi penuh di db-net (Tanpa Port Publik)512 MB
redis-cacheRedis 7 In-Memory Cache & Session Storeredis:7.4-alpine6379/tcpTerisolasi penuh di db-net128 MB
uptime-kumaUptime Kuma Status & Health Monitorlouislam/uptime-kuma:13001/tcp127.0.0.1:3001 (Internal/Tunnel)160 MB
Material Requirement Summary (Copy-Ready)
# =====================================================================
# Generated by InfraCalc Visual Stack Composer (https://infracalc.web.id)
# Project : kampus-app (app.example.com)
# Topology: BOTH_NGINX_AND_CF -> frontend + backend-api -> POSTGRES_16 + redis
# =====================================================================
name: kampus-app

services:
  nginx-proxy:
    image: nginx:1.27-alpine
    container_name: kampus-app-nginx
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certbot/conf:/etc/letsencrypt:ro
    depends_on:
      - frontend
      - backend-api
    networks:
      - edge-net

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: kampus-app-tunnel
    restart: unless-stopped
    command: tunnel --no-autoupdate run
    environment:
      TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
    networks:
      - edge-net

  frontend:
    image: node:20-alpine
    container_name: kampus-app-frontend
    restart: unless-stopped
    working_dir: /app
    environment:
      NODE_ENV: production
      NEXT_PUBLIC_API_URL: https://app.example.com/api
    expose:
      - "3000"
    networks:
      - edge-net

  backend-api:
    image: dunglas/frankenphp:1-php8.3-alpine
    container_name: kampus-app-backend
    restart: unless-stopped
    working_dir: /app
    command: php artisan octane:frankenphp --host=0.0.0.0 --port=8000
    environment:
      APP_ENV: production
      PORT: 8000
      DB_HOST: database
      DB_PORT: 5432
      DB_NAME: ${DB_NAME:-app_db}
      DB_USER: ${DB_USER:-app_user}
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_URL: redis://redis-cache:6379
    expose:
      - "8000"
    depends_on:
      database:
        condition: service_healthy
    networks:
      - edge-net
      - db-net

  database:
    image: postgres:16-alpine
    container_name: kampus-app-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${DB_NAME:-app_db}
      POSTGRES_USER: ${DB_USER:-app_user}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-app_user} -d ${DB_NAME:-app_db}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - db-net

  redis-cache:
    image: redis:7.4-alpine
    container_name: kampus-app-redis
    restart: unless-stopped
    command: redis-server --save 60 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
    networks:
      - db-net

  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: kampus-app-monitoring
    restart: unless-stopped
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - kuma-data:/app/data
    networks:
      - edge-net

networks:
  edge-net:
    driver: bridge
  db-net:
    driver: bridge
    internal: true

volumes:
  db-data:
  redis-data:
  kuma-data:
Nginx Reverse Proxy Configuration (nginx.conf)
# =====================================================================
# Nginx Reverse Proxy Configuration — Generated via https://infracalc.web.id
# Domain: app.example.com
# =====================================================================
upstream frontend_upstream {
    server frontend:3000;
    keepalive 32;
}

upstream backend_upstream {
    server backend-api:8000;
    keepalive 32;
}

server {
    listen 80;
    server_name app.example.com;

    # Security Headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    client_max_body_size 25M;

    # Backend API Route (/api/* -> backend-api:8000)
    location /api/ {
        proxy_pass http://backend_upstream;
        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;
    }

    # Root Route (-> frontend:3000)
    location / {
        proxy_pass http://frontend_upstream;
        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;
    }
}
Linux Script
#!/usr/bin/env bash
# =====================================================================
# Ubuntu/Debian VPS & Docker Firewall Hardening Script
# Generated via https://infracalc.web.id
# =====================================================================
set -euo pipefail

echo "[1/4] Configuring UFW Default Policies..."
sudo ufw default deny incoming
sudo ufw default allow outgoing

echo "[2/4] Allowing SSH Port (22/tcp)..."
sudo ufw allow 22/tcp comment 'SSH Management'
echo "[3/4] Zero-Trust Cloudflare Tunnel Active: Blocking public HTTP/HTTPS direct ports..."
# No inbound 80/443 needed on public VPS IP when using cloudflared!

echo "[4/4] Enabling UFW & Verifying Database Isolation (db-net internal: true)..."
sudo ufw --force enable
sudo ufw status verbose
Environment Variables Template (.env.example)
# .env.example — Copy to .env before running 'docker compose up -d'
DB_NAME=kampus_app_db
DB_USER=kampus_app_user
DB_PASSWORD=ChangeMe_StrongPassword_2026!
DB_ROOT_PASSWORD=ChangeMe_RootSecret_2026!
REDIS_PASSWORD=ChangeMe_RedisSecret_2026!
CLOUDFLARE_TUNNEL_TOKEN=eyJhIjoi...paste_your_tunnel_token_here
Share to WhatsApp

How to Use This Tool

  1. Define project slug, production target domain, and custom Linux VPS SSH management port.
  2. Select components across the 4 architecture tiers: Edge Ingress, Frontend UI, Backend API Engine, and Database & Cache Add-ons.
  3. Inspect the live interactive SVG topology diagram, then copy or download the generated docker-compose.yml, nginx.conf, and setup-firewall.sh scripts.

Worked Example: Campus App (Full-Stack Next.js + Laravel + Postgres + Redis)

Architecture example: Project 'siakad-kampus' targeting 'siakad.univ.ac.id' with Hybrid Nginx + Cloudflare Tunnel, Next.js SSR (:3000), Laravel Octane (:8000), PostgreSQL 16 (:5432), Redis 7 (:6379), and Uptime Kuma (:3001) provisions 7 containers using ~2.1 GB RAM on a 4 GB / 2 vCPU VPS.

Example Input
Project Name (Slug)
Siakad Kampus
Production Domain
siakad.univ.ac.id
Edge Ingress & Proxy Tier
Hybrid Nginx + Cloudflare Tunnel (Double Protection)
Frontend UI Tier
Next.js SSR Frontend (Node 20, Port 3000)
Backend API Engine Tier
Laravel PHP 8.3 Octane / FrankenPHP (Port 8000)
Isolated Database Tier
PostgreSQL 16 Relational DB (Port 5432 Internal)
Enable Redis 7.4 In-Memory Cache (:6379)
Yes / Active
Enable Uptime Kuma Health Monitoring (:3001)
Yes / Active
VPS SSH Port for UFW Firewall
2,222
Calculated Output
Stack Project Name
siakad-kampus
Production Target Domain
siakad.univ.ac.id
Total Active Containers
7 Containers
Estimated RAM Memory Usage
1872 MB
Recommended VPS Specification
4 vCPU / 4 GB RAM
Security Posture & Isolation
ZERO-TRUST TUNNEL (0 Port Web Terbuka di IP Publik + DB Terisolasi)
Material Requirement Summary (Copy-Ready)
# ===================================================================== # Generated by InfraCalc Visual Stack Composer (https://infracalc.web.id) # Project : siakad-kampus (siakad.univ.ac.id) # Topology: BOTH_NGINX_AND_CF -> frontend + backend-api -> POSTGRES_16 + redis # ===================================================================== name: siakad-kampus services: nginx-proxy: image: nginx:1.27-alpine container_name: siakad-kampus-nginx restart: unless-stopped ports: - "127.0.0.1:8080:80" volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro - ./certbot/conf:/etc/letsencrypt:ro depends_on: - frontend - backend-api networks: - edge-net cloudflared: image: cloudflare/cloudflared:latest container_name: siakad-kampus-tunnel restart: unless-stopped command: tunnel --no-autoupdate run environment: TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN} networks: - edge-net frontend: image: node:20-alpine container_name: siakad-kampus-frontend restart: unless-stopped working_dir: /app environment: NODE_ENV: production NEXT_PUBLIC_API_URL: https://siakad.univ.ac.id/api expose: - "3000" networks: - edge-net backend-api: image: dunglas/frankenphp:1-php8.3-alpine container_name: siakad-kampus-backend restart: unless-stopped working_dir: /app command: php artisan octane:frankenphp --host=0.0.0.0 --port=8000 environment: APP_ENV: production PORT: 8000 DB_HOST: database DB_PORT: 5432 DB_NAME: ${DB_NAME:-app_db} DB_USER: ${DB_USER:-app_user} DB_PASSWORD: ${DB_PASSWORD} REDIS_URL: redis://redis-cache:6379 expose: - "8000" depends_on: database: condition: service_healthy networks: - edge-net - db-net database: image: postgres:16-alpine container_name: siakad-kampus-db restart: unless-stopped environment: POSTGRES_DB: ${DB_NAME:-app_db} POSTGRES_USER: ${DB_USER:-app_user} POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - db-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-app_user} -d ${DB_NAME:-app_db}"] interval: 10s timeout: 5s retries: 5 networks: - db-net redis-cache: image: redis:7.4-alpine container_name: siakad-kampus-redis restart: unless-stopped command: redis-server --save 60 1 --loglevel warning --requirepass ${REDIS_PASSWORD} volumes: - redis-data:/data networks: - db-net uptime-kuma: image: louislam/uptime-kuma:1 container_name: siakad-kampus-monitoring restart: unless-stopped ports: - "127.0.0.1:3001:3001" volumes: - kuma-data:/app/data networks: - edge-net networks: edge-net: driver: bridge db-net: driver: bridge internal: true volumes: db-data: redis-data: kuma-data:
Nginx Reverse Proxy Configuration (nginx.conf)
# ===================================================================== # Nginx Reverse Proxy Configuration — Generated via https://infracalc.web.id # Domain: siakad.univ.ac.id # ===================================================================== upstream frontend_upstream { server frontend:3000; keepalive 32; } upstream backend_upstream { server backend-api:8000; keepalive 32; } server { listen 80; server_name siakad.univ.ac.id; # Security Headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; client_max_body_size 25M; # Backend API Route (/api/* -> backend-api:8000) location /api/ { proxy_pass http://backend_upstream; 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; } # Root Route (-> frontend:3000) location / { proxy_pass http://frontend_upstream; 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; } }
Linux Script
#!/usr/bin/env bash # ===================================================================== # Ubuntu/Debian VPS & Docker Firewall Hardening Script # Generated via https://infracalc.web.id # ===================================================================== set -euo pipefail echo "[1/4] Configuring UFW Default Policies..." sudo ufw default deny incoming sudo ufw default allow outgoing echo "[2/4] Allowing SSH Port (2222/tcp)..." sudo ufw allow 2222/tcp comment 'SSH Management' echo "[3/4] Zero-Trust Cloudflare Tunnel Active: Blocking public HTTP/HTTPS direct ports..." # No inbound 80/443 needed on public VPS IP when using cloudflared! echo "[4/4] Enabling UFW & Verifying Database Isolation (db-net internal: true)..." sudo ufw --force enable sudo ufw status verbose
Environment Variables Template (.env.example)
# .env.example — Copy to .env before running 'docker compose up -d' DB_NAME=siakad_kampus_db DB_USER=siakad_kampus_user DB_PASSWORD=ChangeMe_StrongPassword_2026! DB_ROOT_PASSWORD=ChangeMe_RootSecret_2026! REDIS_PASSWORD=ChangeMe_RedisSecret_2026! CLOUDFLARE_TUNNEL_TOKEN=eyJhIjoi...paste_your_tunnel_token_here
Container Services & Port Architecture Table
Container Service NameService RoleDocker Image BaseContainer Internal PortPublic WAN ExposureEstimated RAM
nginx-proxyEdge Reverse Proxy & SSL Terminationnginx:1.27-alpine80, 443127.0.0.1:8080 (Local/Tunnel)96 MB
cloudflaredZero-Trust Outbound Tunnel (Zero Open Inbound Port)cloudflare/cloudflared:latestOutbound QUIC/HTTP2TERTUTUP (0 Port Terbuka di IP Publik VPS)80 MB
frontendNext.js SSR Frontendnode:20-alpine3000/tcpInternal Only (stack-net)384 MB
backend-apiLaravel PHP 8.3 (Octane/FrankenPHP)dunglas/frankenphp:1-php8.3-alpine8000/tcpInternal Only (stack-net)512 MB
databasePostgreSQL 16 Relational DBpostgres:16-alpine5432/tcpTerisolasi penuh di db-net (Tanpa Port Publik)512 MB
redis-cacheRedis 7 In-Memory Cache & Session Storeredis:7.4-alpine6379/tcpTerisolasi penuh di db-net128 MB
uptime-kumaUptime Kuma Status & Health Monitorlouislam/uptime-kuma:13001/tcp127.0.0.1:3001 (Internal/Tunnel)160 MB

Core Concept & Engineering Notes

Designing containerized production server architectures with Docker and Nginx reverse proxies poses frequent reliability and security pitfalls for DevOps practitioners, full-stack software engineers, and IT students. Common misconfigurations include exposing relational database ports directly to public WAN interfaces, failing to isolate internal microservice communication over segmented Docker bridge networks, and under-provisioning host RAM resulting in abrupt process termination by the Linux OOM (Out Of Memory) Killer under high concurrency. The InfraStack Visual Composer provides an interactive, modular studio for designing enterprise container topologies. Adopting a visual Lego-block paradigm, architects can seamlessly select Edge Ingress tiers (Nginx Reverse Proxy with SSL termination, Cloudflare Zero-Trust Outbound Tunnels, or hybrid high-availability configurations), Frontend Application layers (Next.js SSR, React/Vue static SPAs, or headless API setups), Backend API runtimes (Node.js/NestJS, Laravel Octane on FrankenPHP, high-throughput Go Fiber/Gin, or Python FastAPI), and Database tiers (PostgreSQL 16, MySQL 8.4 LTS, or MariaDB 11.4) complemented by Redis 7 caching and Uptime Kuma telemetry. A core tenet of this generator is the automatic synthesis of Dual Docker Bridge Networks. The database and Redis cache containers are strictly quarantined within an internal `db-net` bridge (`internal: true`), prohibiting public WAN port binding and preventing outbound external egress leaks. External client traffic is restricted solely to the `edge-net` tier through reverse proxying or authenticated tunnel ingress. The composer outputs ready-to-deploy, production-hardened `docker-compose.yml`, `nginx.conf`, Linux UFW firewall rules, and a populated `.env.example` file.

How It Was Calculated (Formulas & Steps)

Frequently Asked Questions (FAQ)

Why must database containers reside in an internal network without host port binding?

Binding ports 5432 or 3306 directly to the host exposes databases to public internet brute-force attacks and zero-day exploits. Defining internal: true ensures databases are only reachable by backend containers on the shared private bridge network.

What are the advantages of a Hybrid Nginx + Cloudflare Zero-Trust Tunnel architecture?

Cloudflare Tunnel conceals the VPS public IP completely with zero open inbound firewall ports, while local Nginx handles microservice path routing (/api/*), gzip/brotli compression, and local caching.

What is the recommended minimum VPS RAM to run this complete Docker stack?

For a standard production stack (Nginx + Next.js + Backend API + Database + Redis), a VPS with at least 2 GB to 4 GB RAM and 2 GB Linux Swap is recommended to prevent OOM Killer termination during traffic spikes.

šŸ”¬ Scientific Methodology & Normative Verification

Engineering Sensitivity Analysis, Response Curve & Technical Citation

āœ“ Calibrated to ISO/IEC/IEEE/TIA Clauses

1. 1. 3-Point Engineering Sensitivity & Tolerance Envelope

Comparative evaluation across theoretical laboratory bounds (0% loss), current nominal operating point, and conservative field safety bounds (±15% thermal/aging derating).

Evaluated Parameter Ideal Theoretical Bound Nominal Operating Point Conservative Safety Bound (±15%) Engineering Derating Rule
Total Active Containers 6.3 7 8.05 Engineering Safety Margin (+15% Overhead)
Estimated RAM Memory Usage 1,685 MB 1,872 MB 2,153 MB Engineering Safety Margin (+15% Overhead)

2. 2. Mathematical Function Curve & Operating Coordinate (xā‚€, yā‚€)

MATHEMATICAL RESPONSE CURVE: TOTAL ACTIVE CONTAINERS VS SSH CUSTOM PORT Conservative Engineering Bound (+15% Safety Margin) 8.8 13.2 17.6 22 26.4 30.8 35.2 (xā‚€=22, yā‚€=7) Variabel Independen (x): Ssh Custom Port

3. 3. Physical Constants & Normative Standard Clauses

R_loop(Cat6, 20°C) = 14 Ω/100m ANSI/TIA-568.2-D & IEEE 802.3bt

DC Loop Resistance for 23 AWG Solid Copper Cat6

Clause 6.4.1 / Table 145-1 — Nominal 23 AWG solid copper loop resistance at 20°C is 14.0 Ī©/100m (TIA maximum ceiling is 18.8 Ī©/100m).

α_opt(1490nm) = 0.25 dB/km ITU-T Rec. G.652.D & G.984.2

Single-Mode Optical Fiber Attenuation Coefficient at 1490 nm

Table 1 / Class B+ & C+ Optical Path — Typical G.652.D attenuation at 1490 nm downstream is 0.22–0.25 dB/km (1310 nm upstream: 0.35 dB/km).

α_Cu(20°C) = 0.00393 °C⁻¹ IEC 60028

Temperature Coefficient of Resistance for Copper

International Annealed Copper Standard — Used in thermal derating equation: R(T) = R_20 Ɨ [1 + 0.00393 Ɨ (T - 20)].

4. 4. Independent Technical & Academic Citation (IEEE / APA 7th / BibTeX / LaTeX)

Use the standard citation formats below to reference this computational methodology in engineering specifications, audit reports, or academic papers.

Format IEEE & APA 7th Edition

[IEEE] InfraCalc Engineering Team, "Docker, Nginx & Linux Stack Visual Composer — Standard Engineering Computational Instrument," InfraCalc Technical Suite, 2026. [Online]. Available: https://infracalc.web.id/en/tools/docker-nginx-stack-composer. [Accessed: 2026-11-08].

[APA 7th] InfraCalc Engineering Team. (2026). Docker, Nginx & Linux Stack Visual Composer (Production release 2026-11-08) [Engineering computational software]. InfraCalc. https://infracalc.web.id/en/tools/docker-nginx-stack-composer

BibTeX & LaTeX Derivation Snippet
@software{infracalc_docker_nginx_stack_composer_2026,
  author = {{InfraCalc Engineering Team}},
  title = {{Docker, Nginx & Linux Stack Visual Composer --- InfraCalc Engineering Suite}},
  year = {2026},
  publisher = {InfraCalc.web.id},
  url = {https://infracalc.web.id/en/tools/docker-nginx-stack-composer},
  urldate = {2026-11-08}
}

% LaTeX Engineering Derivation — Generated via https://infracalc.web.id/en/tools/docker-nginx-stack-composer
\begin{equation}
  \text{Model: } Total Stack RAM (MB) = Σ(RAM Ingress + RAM Frontend + RAM Backend + RAM Database + RAM Addons)
\end{equation}
% Parameter Input Terukur: projectName = kampus-app, \; domainName = app.example.com, \; edgeIngress = BOTH_NGINX_AND_CF, \; frontendStack = NEXTJS_NODE
% Hasil Evaluasi Numerik : stackName = \mathbf{kampus-app}, \; targetDomain = \mathbf{app.example.com}, \; totalContainersCount = \mathbf{7}