폐쇄망 NetBox 컨테이너 번들 구축 가이드 (Rocky Linux 8.10 + Podman)

목표: Rocky Linux 8.10 환경에서, 외부 인터넷이 완전히 차단된 폐쇄망에 NetBox를 컨테이너(Podman)로 구축한다.

전략: 인터넷이 되는 온라인 서버에서 번들(이미지 + RPM + 설정 + 스크립트) 을 생성하고, 이를 폐쇄망 서버로 옮겨서 그대로 재생성한다.

이 문서는 실제 구축 중 겪었던 문제들(의존 패키지 누락, Waiting on DB, SECRET_KEY 오류, 컨테이너 엔트리포인트 꼬임, DNS 문제 등)을 모두 반영해, Rocky 8.10에서 그대로 따라 해도 동작하는 수준으로 정리한 가이드이다.


0. 전체 구성 개요

0-1. 서버 역할

  1. 온라인 번들 제작 서버 (Online Build Host)
    • OS: Rocky Linux 8.10 (또는 Podman 사용 가능한 RHEL8 계열)
    • 인터넷 연결 가능
    • 역할:
      • NetBox / Postgres / Redis 컨테이너 이미지 Pull & Save
      • Podman 및 관련 의존 패키지 RPM 다운로드
      • env 파일, 실행 스크립트 준비
      • 전체를 하나의 tar.gz 번들로 패키징
  2. 폐쇄망 NetBox 서버 (Offline NetBox Host)
    • OS: Rocky Linux 8.10 Minimal 설치
    • 인터넷 연결 완전 차단(외부로 나갈 수 없음)
    • 역할:
      • 온라인 서버에서 만들어 온 tar.gz 번들을 복사
      • Podman 및 의존 패키지 설치 (로컬 RPM)
      • 컨테이너 이미지 로드 후 스크립트로 NetBox Pod 및 컨테이너 기동

0-2. 컨테이너 / Pod 구조

Podman의 Pod 기능을 활용하여, NetBox 관련 컨테이너들을 하나의 Pod 안에 넣는다.

  • Pod 이름: netbox-pod
  • 컨테이너 구성:
    • netbox-postgres : PostgreSQL 16 (DB)
    • netbox-redis : Redis 7 (tasks + cache 겸용, DB 번호로 분리)
    • netbox : NetBox 웹 (gunicorn)
    • netbox-worker : NetBox RQ worker
    • netbox-housekeeping : NetBox housekeeping job
  • 네트워크:
    • Pod 외부 노출: 호스트 8000 → Pod 내 NetBox 컨테이너 8080
    • Pod 내부 통신: 모든 컨테이너가 동일 네트워크 네임스페이스 공유 → 서로를 127.0.0.1 으로 접근

중요 설계 포인트

  • Podman Pod 내부에서는 Docker Compose처럼 DB_HOST=postgres 식의 DNS 이름 사용보다, “ 기반 접근이 단순하고 안정적이다.
  • Redis를 두 개 컨테이너로 나누면 Pod 내부에서 동일 포트(6379) 충돌 가능성이 있기 때문에, Redis 컨테이너는 하나만 사용하고 DB 번호(0, 1)로 tasks/cache를 분리한다.

0-3. 번들 디렉터리 구조

온라인 번들 제작 서버에서 최종적으로 다음 구조를 만든 후, 전체를 tar로 묶어 폐쇄망 서버로 옮긴다.

/opt/netbox-container-bundle-v4.4.6-3.4.2
├── rpms/                    # Podman 및 의존 패키지 RPM 묶음
├── images/
│   ├── netbox.tar              # NetBox 컨테이너 이미지
│   ├── postgres16-alpine.tar   # PostgreSQL 16-alpine 컨테이너 이미지
│   └── redis7-alpine.tar       # Redis 7-alpine 컨테이너 이미지
├── env/
│   ├── netbox.env           # NetBox 환경 변수
│   ├── postgres.env         # PostgreSQL 환경 변수
│   └── redis.env            # Redis 환경 변수
└── podman/
    ├── run-netbox-pod.sh    # Pod 및 컨테이너 생성/실행 스크립트
    └── reset-netbox-pod.sh  # Pod/컨테이너/볼륨 초기화 스크립트

최종 번들 파일 예시:

/opt/netbox-container-bundle-v4.4.6-3.4.2.tar.gz

1. 온라인 번들 제작 서버 작업 (Rocky 8.10, 인터넷 가능)

이 절차는 외부 인터넷에 접근 가능한 Rocky 8.10 서버에서 수행한다.

1-1. 기본 변수 및 디렉터리 생성

NETBOX_TAG="v4.4.6-3.4.2"        # 사용할 NetBox 컨테이너 태그
BUNDLE_ROOT="/opt/netbox-container-bundle-${NETBOX_TAG}"

sudo mkdir -p "${BUNDLE_ROOT}"/{rpms,images,env,podman}
sudo chown -R "$(id -u)":"$(id -g)" "${BUNDLE_ROOT}"

1-2. Podman 설치 및 RPM 번들 생성 (Rocky 8.10용)

Rocky 8.10에서 Podman과 의존 패키지들을 모두 폐쇄망에서도 설치 가능하도록 rpms/ 에 모은다.

  1. dnf-plugins-core 설치 (온라인 서버 관리용)
sudo dnf install -y dnf-plugins-core
  1. Podman 및 필수 의존 패키지를 다운로드-only로 수집

Rocky 8 계열에서 Podman이 요구하는 주요 패키지들을 한 번에 모아준다. (실제 의존 패키지는 환경에 따라 약간 다를 수 있으므로, 필요시 dnf repoquery --requires podman 등으로 추가 보완 가능)

sudo dnf download --resolve \
  --downloaddir="${BUNDLE_ROOT}/rpms" \
  podman \
  conmon \
  container-selinux \
  containernetworking-plugins \
  containers-common \
  criu \
  dnsmasq \
  fuse-common \
  fuse-overlayfs \
  fuse3 \
  fuse3-libs \
  libnet \
  libslirp \
  podman-catatonit \
  podman-plugins \
  protobuf-c \
  runc \
  shadow-utils-subid \
  slirp4netns \
  podman-gvproxy \
  tar

주의

  • 이미 Podman이 설치된 상태에서 dnf install --downloadonly podman 만 사용하면 Nothing to do 로 끝나면서 RPM이 내려받히지 않는다.
  • 반드시 dnf download --resolvednf reinstall --downloadonly 를 사용해야 한다.

1-3. 컨테이너 이미지 Pull & Save (각각 분리 저장 필수)

NetBox, Postgres, Redis 이미지를 Pull 한 뒤, 각각 따로 tar 파일로 저장한다. 여러 이미지를 한 번에 podman save 하면, 오프라인에서 로드 시 IMAGE ID/Tag가 꼬여서 서로 다른 이미지가 같은 ID로 보이는 문제가 발생할 수 있으므로 반드시 분리 저장한다.

cd "${BUNDLE_ROOT}/images"

# 1) 이미지 Pull
podman pull "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"
podman pull docker.io/postgres:16-alpine
podman pull docker.io/redis:7-alpine

# 2) 이미지 Tar 로 각각 저장
podman save \
  -o netbox.tar \
  "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"

podman save \
  -o postgres16-alpine.tar \
  docker.io/postgres:16-alpine

podman save \
  -o redis7-alpine.tar \
  docker.io/redis:7-alpine

이렇게 저장해두면 폐쇄망 서버에서 podman loadpodman images 를 찍었을 때 NetBox / Postgres / Redis 각각 서로 다른 IMAGE ID 로 표시되어, 이후 디버깅 시에도 이미지가 뒤섞이지 않는다.


1-4. env 파일 작성

예시에서는 모든 비밀번호를 임시로 p@ssw0rd 로 통일한다. 실제 운영 시에는 반드시 더 강한 비밀번호로 교체할 것.

1-4-1. PostgreSQL env (env/postgres.env)

cat > "${BUNDLE_ROOT}/env/postgres.env" << 'EOF'
POSTGRES_DB=netbox
POSTGRES_USER=netbox
POSTGRES_PASSWORD=p@ssw0rd
EOF
  • POSTGRES_DB : 생성할 DB 이름 (절대 IP가 아님)
  • POSTGRES_USER : DB 계정 이름
  • POSTGRES_PASSWORD : DB 계정 비밀번호

1-4-2. Redis env (env/redis.env)

cat > "${BUNDLE_ROOT}/env/redis.env" << 'EOF'
REDIS_PASSWORD=p@ssw0rd
EOF

1-4-3. NetBox env (env/netbox.env)

먼저, NetBox 컨테이너 안에서 SECRET_KEY를 생성한다.

SECRET_KEY=$(podman run --rm \
  "docker.io/netboxcommunity/netbox:${NETBOX_TAG}" \
  python /opt/netbox/netbox/generate_secret_key.py)

echo "Generated SECRET_KEY: ${SECRET_KEY}"

그 다음 env 파일을 작성한다.

cat > "${BUNDLE_ROOT}/env/netbox.env" << EOF
############################
# Database
############################
DB_HOST=127.0.0.1
DB_NAME=netbox
DB_USER=netbox
DB_PASSWORD=p@ssw0rd
DB_PORT=5432

############################
# Redis (tasks)
############################
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DATABASE=0
REDIS_PASSWORD=p@ssw0rd
REDIS_SSL=false
REDIS_INSECURE_SKIP_TLS_VERIFY=false

############################
# Redis (cache)
############################
REDIS_CACHE_HOST=127.0.0.1
REDIS_CACHE_PORT=6379
REDIS_CACHE_DATABASE=1
REDIS_CACHE_PASSWORD=p@ssw0rd
REDIS_CACHE_SSL=false
REDIS_CACHE_INSECURE_SKIP_TLS_VERIFY=false

############################
# NetBox 공통 설정
############################
SECRET_KEY=${SECRET_KEY}

# NetBox가 허용할 호스트/IP
# 폐쇄망/내부용이라면 가장 간단하게 전체 허용(*)으로 두는 것이 400 Bad Request를 피하는 데 유리함.
ALLOWED_HOSTS=*

# 폐쇄망 배포 시 권장 옵션
ISOLATED_DEPLOYMENT=true

# 초기 슈퍼유저
SUPERUSER_USERNAME=netbox
SUPERUSER_PASSWORD=p@ssw0rd
SUPERUSER_EMAIL=netbox@example.local

# 타임존
TIME_ZONE=Asia/Seoul

# DB 대기 디버그 – 문제 발생시 전체 trace 확인용
DB_WAIT_DEBUG=1
EOF

중요 매칭 규칙

  • POSTGRES_DBDB_NAME → 둘 다 netbox
  • POSTGRES_USERDB_USER → 둘 다 netbox
  • POSTGRES_PASSWORDDB_PASSWORD → 둘 다 p@ssw0rd

DB_HOSTDB 서버의 IP/호스트, 여기서는 Pod 내부 공유 네임스페이스 기준으로 127.0.0.1 을 사용한다. POSTGRES_DBDB 이름 이므로 절대 127.0.0.1 같은 IP로 바꾸면 안 된다.


1-5. Podman 실행 스크립트 작성 (podman/run-netbox-pod.sh)

폐쇄망 서버에서 Pod 및 컨테이너를 한 번에 올리는 스크립트를 작성한다.

cat > "${BUNDLE_ROOT}/podman/run-netbox-pod.sh" << 'EOF'
#!/usr/bin/env bash
set -euo pipefail

NETBOX_TAG="v4.4.6-3.4.2"
BUNDLE_ROOT="/opt/netbox-container-bundle-${NETBOX_TAG}"

NETBOX_ENV="${BUNDLE_ROOT}/env/netbox.env"
PG_ENV="${BUNDLE_ROOT}/env/postgres.env"
REDIS_ENV="${BUNDLE_ROOT}/env/redis.env"

# 0) 이미지가 로드되어 있는지 간단 체크 (없으면 경고만 출력)
if ! podman image exists "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"; then
  echo "[WARN] NetBox image not found locally. 폐쇄망 서버에서는 먼저 podman load 를 실행해야 합니다." >&2
fi

# 1) Pod 생성
if podman pod exists netbox-pod; then
  echo "[INFO] netbox-pod already exists."
else
  echo "[INFO] Creating pod netbox-pod (host port 8000 -> container 8080)"
  podman pod create --name netbox-pod -p 8000:8080
fi

# 2) 볼륨 생성 (이미 존재하면 무시)
podman volume create netbox-postgres-data >/dev/null 2>&1 || true
podman volume create netbox-redis-data    >/dev/null 2>&1 || true
podman volume create netbox-media-files   >/dev/null 2>&1 || true
podman volume create netbox-reports-files >/dev/null 2>&1 || true
podman volume create netbox-scripts-files >/dev/null 2>&1 || true

# 3) PostgreSQL 컨테이너
if podman container exists netbox-postgres; then
  echo "[INFO] netbox-postgres already exists."
else
  echo "[INFO] Starting netbox-postgres..."
  podman run -d --name netbox-postgres --pod netbox-pod \
    --env-file "${PG_ENV}" \
    -v netbox-postgres-data:/var/lib/postgresql/data \
    docker.io/postgres:16-alpine
fi

# 4) Redis 컨테이너 (tasks + cache 겸용)
if podman container exists netbox-redis; then
  echo "[INFO] netbox-redis already exists."
else
  echo "[INFO] Starting netbox-redis..."
  podman run -d --name netbox-redis --pod netbox-pod \
    --env-file "${REDIS_ENV}" \
    -v netbox-redis-data:/data \
    docker.io/redis:7-alpine \
    sh -c 'redis-server --appendonly yes --requirepass "$REDIS_PASSWORD"'
fi

# 5) NetBox 웹 컨테이너
if podman container exists netbox; then
  echo "[INFO] netbox already exists."
else
  echo "[INFO] Starting netbox web..."
  podman run -d --name netbox --pod netbox-pod \
    --env-file "${NETBOX_ENV}" \
    -v netbox-media-files:/opt/netbox/netbox/media \
    -v netbox-reports-files:/opt/netbox/netbox/reports \
    -v netbox-scripts-files:/opt/netbox/netbox/scripts \
    "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"
fi

# 6) NetBox worker 컨테이너
if podman container exists netbox-worker; then
  echo "[INFO] netbox-worker already exists."
else
  echo "[INFO] Starting netbox-worker..."
  podman run -d --name netbox-worker --pod netbox-pod \
    --env-file "${NETBOX_ENV}" \
    "docker.io/netboxcommunity/netbox:${NETBOX_TAG}" \
    /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py rqworker
fi

# 7) NetBox housekeeping 컨테이너
#   - 최신 NetBox 이미지에는 /opt/netbox/housekeeping.sh 가 없을 수 있으므로
#     manage.py housekeeping 을 주기적으로 실행하는 방식으로 구성한다.
if podman container exists netbox-housekeeping; then
  echo "[INFO] netbox-housekeeping already exists."
else
  echo "[INFO] Starting netbox-housekeeping..."
  podman run -d --name netbox-housekeeping --pod netbox-pod \
    --env-file "${NETBOX_ENV}" \
    "docker.io/netboxcommunity/netbox:${NETBOX_TAG}" \
    sh -c 'while true; do \
      /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py housekeeping; \
      sleep 3600; \
    done'
fi

# 상태 출력
echo
echo "[INFO] Pod status:"
podman pod ps

echo
echo "[INFO] Containers in netbox-pod:"
podman ps --pod

echo
echo "[INFO] Access NetBox via: http://<이 서버 IP>:8000"
EOF

chmod +x "${BUNDLE_ROOT}/podman/run-netbox-pod.sh"

1-6. 초기화 스크립트 작성 (podman/reset-netbox-pod.sh)

기존에 잘못 생성된 컨테이너/볼륨이 꼬여 있는 경우를 대비해, 완전 초기화용 스크립트를 함께 준비한다.

cat > "${BUNDLE_ROOT}/podman/reset-netbox-pod.sh" << 'EOF'
#!/usr/bin/env bash
set -euo pipefail

echo "[WARN] This will REMOVE netbox pod, containers, and related volumes."
echo "[WARN] All NetBox data (DB, Redis, media) will be lost."

# 1) Pod 및 컨테이너 삭제
podman pod rm -f netbox-pod 2>/dev/null || true
podman rm -f netbox netbox-postgres netbox-redis netbox-worker netbox-housekeeping 2>/dev/null || true

# 이름에 netbox/postgres/redis 가 들어간 컨테이너들 추가 제거
podman ps -a --format '{{.ID}} {{.Names}}' | egrep 'netbox|postgres|redis' | awk '{print $1}' | xargs -r podman rm -f

# 2) 볼륨 삭제
for v in $(podman volume ls --format '{{.Name}}' | egrep 'netbox|postgres|redis'); do
  echo "Removing volume: $v"
  podman volume rm -f "$v" || true
done

# 3) 필요시 미사용 리소스 정리 (선택)
podman volume prune -f || true
# podman system prune -f || true


echo "[INFO] Reset complete. You can now re-run run-netbox-pod.sh."
EOF

chmod +x "${BUNDLE_ROOT}/podman/reset-netbox-pod.sh"

1-7. 번들 tar.gz 생성

cd /opt
sudo tar czf "netbox-container-bundle-v4.4.6-3.4.2.tar.gz" "netbox-container-bundle-v4.4.6-3.4.2"

생성된 tar.gz 파일을 폐쇄망 NetBox 서버scp, USB, 망연계 등으로 전달한다.


2. 폐쇄망 NetBox 서버 작업 (Rocky 8.10, 인터넷 단절)

2-1. 번들 전개

예시로 /opt 에 배치한다고 가정한다.

cd /opt
sudo tar xzf netbㅊㅇox-container-bundle-v4.4.6-3.4.2.tar.gz
sudo chown -R root:root /opt/netbox-container-bundle-v4.4.6-3.4.2

2-2. Podman 및 의존 패키지 설치 (로컬 RPM)

폐쇄망 서버에서는 외부 repo를 끄고, 번들 안의 RPM만 사용한다.

cd /opt/netbox-container-bundle-v4.4.6-3.4.2/rpms

# 외부 repo 비활성화 후 로컬 RPM만 사용
sudo dnf localinstall -y ./*.rpm --disablerepo='*'

설치 후 Podman 버전 확인:

podman --version

문제 없이 출력되면 OK.


2-3. 컨테이너 이미지 로드

cd /opt/netbox-container-bundle-v4.4.6-3.4.2/images

sudo podman load -i netbox.tar
sudo podman load -i postgres16-alpine.tar
sudo podman load -i redis7-alpine.tar

podman images | egrep 'netboxcommunity/netbox|postgres|redis'

정상이라면 NetBox / Postgres / Redis 가 각각 다른 IMAGE ID 를 가진 상태로 보인다.


2-4. 최초 기동 (Pod 및 컨테이너 생성)

cd /opt/netbox-container-bundle-v4.4.6-3.4.2/podman
sudo ./run-netbox-pod.sh

정상적으로 기동되면 마지막에 대략 다음과 같은 출력이 보인다.

[INFO] Pod status:
POD ID        NAME        STATUS   ...
xxxx          netbox-pod  Running

[INFO] Containers in netbox-pod:
CONTAINER ID  IMAGE                              STATUS         NAMES
...           postgres:16-alpine                 Up ...         netbox-postgres
...           redis:7-alpine                     Up ...         netbox-redis
...           netboxcommunity/netbox:v4.4.6-...  Up ...         netbox
...           netboxcommunity/netbox:v4.4.6-...  Up ...         netbox-worker
...           netboxcommunity/netbox:v4.4.6-...  Up ...         netbox-housekeeping
...           <infra>                            Up ...         <pod>-infra

2-5. NetBox 접속 확인

브라우저에서:

http://<폐쇄망 NetBox 서버 IP>:8000

초기 로그인 계정은 env/netbox.env 에 설정한 값을 사용한다.

사용자명: admin
비밀번호: p@ssw0rd

최초 로그인 후 반드시 비밀번호 및 SUPERUSER 관련 설정을 변경한다.


3. 문제 발생 시 트러블슈팅 패턴

3-1. 기본 확인 루틴

  1. Pod 및 컨테이너 상태 확인
podman pod ps
podman ps -a --pod
  1. 특정 컨테이너 로그 확인 (웹 / DB / Redis / 워커 / 하우스키핑)
# NetBox 웹
podman logs --tail 100 netbox

# PostgreSQL
podman logs --tail 100 netbox-postgres

# Redis
podman logs --tail 100 netbox-redis

# Worker (RQ)
podman logs --tail 100 netbox-worker

# Housekeeping
podman logs --tail 100 netbox-housekeeping
  1. NetBox env 확인
cat /opt/netbox-container-bundle-v4.4.6-3.4.2/env/netbox.env

3-2. 자주 발생하는 에러 & 해결

3-2-1. SECRET_KEY must be at least 50 characters 에러

  • 원인: env/netbox.envSECRET_KEY 길이가 50자 미만이거나, 따옴표 포함 등으로 잘못 설정됨.
  • 해결:
    1. 온라인 서버 또는 폐쇄망 서버의 NetBox 이미지에서 key 재생성
      podman run --rm \
        docker.io/netboxcommunity/netbox:v4.4.6-3.4.2 \
        python /opt/netbox/netbox/generate_secret_key.py
      
    2. 생성된 키를 env/netbox.envSECRET_KEY=따옴표 없이 그대로 넣는다.
    3. 컨테이너 재기동 (필요시 reset-netbox-pod.shrun-netbox-pod.sh).

3-2-2. OperationalError: connection to server at "127.0.0.1", port 5432 failed (DB 접속 실패)

  • 원인 후보:
    • netbox-postgres 컨테이너가 정상적으로 뜨지 않았거나, 바로 종료됨
    • Postgres env (postgres.env) 와 NetBox env (netbox.env) 의 DB 설정 불일치
  • 확인:
    podman ps -a | egrep 'netbox|postgres'
    podman logs --tail 100 netbox-postgres
    
  • 해결:
    • 우선 postgres.envnetbox.envDB_NAME/DB_USER/DB_PASSWORD 값이 완전히 일치하는지 확인
    • 이상한 엔트리포인트(예: python /opt/netbox/...) 로그가 netbox-postgres 에 보이면, 초기화 스크립트로 완전 리셋 후 다시 run-netbox-pod.sh 실행

3-2-3. Temporary failure in name resolution (DB/Redis 호스트 이름 해석 실패)

  • 원인: DB_HOST=postgres, REDIS_HOST=redis 등으로 설정하고, Podman Pod에서 DNS 이름이 안 풀리는 경우
  • 해결:
    • 이 가이드처럼 모든 DB/Redis 호스트를 “ 로 설정한다.

3-2-4. relation "core_job" does not exist (worker 컨테이너 에러)

  • 증상:
    • netbox-worker 로그에 django.db.utils.ProgrammingError: relation "core_job" does not exist 발생 후 컨테이너가 종료됨.
  • 원인:
    • NetBox DB 마이그레이션이 완료되기 전에 worker 컨테이너가 먼저 뜨면서, 아직 생성되지 않은 core_job 테이블을 조회해 에러가 발생한 경우.
  • 해결:
    1. 웹 컨테이너에서 한 번 더 마이그레이션 수행
      podman exec -it netbox \
        /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py migrate
      
    2. 기존 worker 컨테이너 삭제 후 재생성
      podman rm -f netbox-worker
      
      podman run -d --name netbox-worker --pod netbox-pod \
        --env-file /opt/netbox-container-bundle-v4.4.6-3.4.2/env/netbox.env \
        docker.io/netboxcommunity/netbox:v4.4.6-3.4.2 \
        /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py rqworker
      

3-2-5. /opt/netbox/housekeeping.sh not found (housekeeping 컨테이너 에러)

  • 증상:
    • 예전 이미지 기준 스크립트로 netbox-housekeeping 을 띄우면 [FATAL tini] exec /opt/netbox/housekeeping.sh failed: No such file or directory 메시지가 출력되며 바로 종료될 수 있다.
  • 원인:
    • 사용하는 NetBox 이미지 버전에서 더 이상 /opt/netbox/housekeeping.sh 스크립트를 제공하지 않는 경우.
  • 해결:
    • 이 가이드처럼 run-netbox-pod.sh 에서 housekeeping 컨테이너를 manage.py housekeeping 을 주기적으로 실행하는 방식으로 구성한다.
      podman run -d --name netbox-housekeeping --pod netbox-pod \
        --env-file "${NETBOX_ENV}" \
        "docker.io/netboxcommunity/netbox:${NETBOX_TAG}" \
        sh -c 'while true; do \
          /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py housekeeping; \
          sleep 3600; \
        done'
      
  • 참고:
    • NetBox 최신 버전에서는 대부분의 housekeeping 작업이 내부 Job 스케줄러로 자동 처리되며, 위 명령은 주기적인 수동 정리 역할을 보완하는 용도로 사용한다.

4. 최종 체크리스트 (Rocky 8.10 폐쇄망에서 “정상 구축” 상태)

  1. 이미지 상태
podman images | egrep 'netboxcommunity/netbox|postgres|redis'
  • NetBox, Postgres, Redis 각각 서로 다른 IMAGE ID 를 가지고 있어야 한다.
  1. Pod/컨테이너 상태
podman ps -a --pod
  • netbox-postgres : Up
  • netbox-redis : Up
  • netbox : Up
  • netbox-worker : Up (RQ worker 로그에서 high/default/low 큐 리스닝 중)
  • netbox-housekeeping : Up (또는 주기 실행 루프 형태)
  1. 웹 접속
  • 브라우저에서 http://<폐쇄망 서버 IP>:8000 접속 시 NetBox 로그인 페이지가 떠야 한다.
  • Bad Request (400) 이 뜨지 않아야 하며, 만약 뜬다면 ALLOWED_HOSTS 설정을 다시 확인한다.
  1. 로그인
  • netbox / p@ssw0rd 로 로그인 가능해야 한다.
  • 로그인 후 즉시 비밀번호를 변경하고, 필요 시 createsuperuser 로 개인용 관리자 계정을 추가한다.

위 체크리스트까지 모두 통과하면, Rocky 8.10 폐쇄망 환경에서 NetBox 컨테이너 번들이 “오류 없이 완벽하게 구축된” 상태라고 볼 수 있다.