#!/bin/bash
# 실습 #3 ③ — 네트워크 3종: bridge / host / none
# - bridge : 기본. 컨테이너끼리 격리되지만 같은 user-defined bridge 안에선 컨테이너 이름이 곧 DNS.
# - host   : 호스트 네트워크 그대로 사용. 격리 없음. 성능·포트 매핑 회피.
# - none   : 네트워크 인터페이스 자체 없음 (lo 만). 배치 작업·격리 최강.
set -e

cleanup() {
    sudo docker rm -f db-net web-net web-host alp-none 2>/dev/null || true
    sudo docker network rm app-net 2>/dev/null || true
}
trap cleanup INT TERM EXIT

# 1) user-defined bridge 만들기 — 기본 docker0 와 분리된 격리망
sudo docker network create app-net >/dev/null
echo "=== app-net 생성 ==="
sudo docker network inspect app-net --format '{{.IPAM.Config}}'

# 2) 같은 bridge 에 db + web 띄우기 — 컨테이너 이름으로 통신
sudo docker run -d --name db-net --network app-net \
    -e POSTGRES_PASSWORD=secret postgres:16-alpine
sudo docker run -d --name web-net --network app-net \
    -p 8090:80 nginx:1.27

sleep 2
echo
echo "=== web-net → db-net 이름 해석 (DNS) ==="
sudo docker exec web-net getent hosts db-net || \
    sudo docker exec web-net sh -c 'apk add --no-cache bind-tools >/dev/null 2>&1; nslookup db-net' || true

# 3) host 네트워크 — 포트 매핑 불필요, 호스트 80 그대로 잡음
#    주의: 호스트 80 이 비어 있어야 함. 충돌 시 8090 등을 사용.
HOST_PORT_FREE=0
ss -tln 2>/dev/null | grep -q ':80 ' || HOST_PORT_FREE=1
if [ "$HOST_PORT_FREE" = "1" ]; then
    sudo docker run -d --name web-host --network host nginx:1.27
    sleep 1
    echo
    echo "=== host 네트워크 — 매핑 없이 호스트 80 응답 ==="
    curl -sI http://localhost | head -2
    sudo docker rm -f web-host >/dev/null
else
    echo
    echo "→ 호스트 80 이미 사용 중. host 네트워크 시연 건너뜀."
fi

# 4) none 네트워크 — lo 만 존재
sudo docker run -d --name alp-none --network none alpine sleep 60
echo
echo "=== none 네트워크 — 인터페이스 lo 뿐 ==="
sudo docker exec alp-none ip -br a

# 5) 네트워크 목록 / inspect
echo
echo "=== 전체 네트워크 ==="
sudo docker network ls

echo
echo "=== app-net 에 붙은 컨테이너 ==="
sudo docker network inspect app-net --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{println}}{{end}}'

echo
echo "관전 포인트:"
echo "  - bridge: 외부에서 들어가려면 -p HOST:CONT 매핑 필요"
echo "  - host : 매핑 불필요. 보안·포트 충돌 위험 ↑"
echo "  - none : 인바운드/아웃바운드 둘 다 막힘"
