폐쇄망 NetBox 구축은 인터넷이 되는 서버에서 패키지와 OCI 이미지를 수집한 뒤 무결성을 검증해 오프라인 서버로 반입하는 작업이다. 단순히 이미지 파일만 복사하면 Podman 의존 RPM, 이미지 태그, 데이터베이스 초기화, 보안 설정과 재부팅 후 자동 시작 단계에서 실패하기 쉽다.

이 가이드는 Rocky Linux 8.10 x86_64의 rootful Podman을 기준으로 한다. 2026년 7월 20일 확인한 예시 버전은 NetBox 컨테이너 v4.6.5-5.0.2, PostgreSQL 18-alpine, Valkey 9.1-alpine이다. 운영 반입 전에는 반드시 공식 릴리스 노트와 레지스트리의 다이제스트를 다시 확인한다.

폐쇄망 NetBox 구축 흐름: 버전 고정, 온라인 번들 수집, SHA-256 검증, Podman 기동
폐쇄망 NetBox 구축을 위한 온라인 수집부터 기동·백업까지의 흐름

폐쇄망 NetBox 구축 전제와 검증 기준

  • 번들 제작 서버와 폐쇄망 서버의 Rocky Linux 마이너 버전, CPU 아키텍처와 활성 저장소를 맞춘다.
  • 컨테이너 이미지는 latest 대신 정확한 버전 태그를 사용하고 다이제스트를 기록한다.
  • RPM은 --resolve --alldeps로 이미 설치된 의존성까지 내려받는다.
  • 온라인 환경에서 번들을 만든 뒤 동일 조건의 테스트 서버에서 오프라인 설치를 재현한다.
  • 운영에서는 rootful과 rootless Podman을 섞지 않는다. 이 글은 모든 폐쇄망 명령을 sudo podman으로 통일한다.
cat /etc/rocky-release
uname -m
sudo dnf repolist --enabled
sudo podman --version
구성 요소 이 가이드의 고정값 검증 포인트
NetBox Docker v4.6.5-5.0.2 NetBox와 netbox-docker 호환 태그
PostgreSQL 18-alpine 기존 데이터 볼륨과 메이저 버전 호환성
Valkey 9.1-alpine tasks와 cache 인스턴스 분리
호스트 Rocky Linux 8.10 동일 아키텍처·저장소·보안 정책

폐쇄망 NetBox 구축 아키텍처

NetBox 웹과 worker, PostgreSQL, tasks용 Valkey, cache용 Valkey를 하나의 Pod에 넣는다. 같은 Pod의 컨테이너는 네트워크 네임스페이스를 공유하므로 애플리케이션은 127.0.0.1로 데이터베이스와 Valkey에 접근할 수 있다. 외부에는 NetBox의 8080만 호스트 8000으로 게시한다.

netbox-pod
├── netbox             127.0.0.1:8080  ← host:8000
├── netbox-worker      RQ worker
├── netbox-postgres    127.0.0.1:5432
├── netbox-valkey      127.0.0.1:6379  (tasks)
└── netbox-valkey-cache 127.0.0.1:6380 (cache)

컨테이너 네트워크 개념이 익숙하지 않다면 내부 글인 컨테이너 개념 실습을 먼저 참고할 수 있다.

폐쇄망 NetBox 구축용 온라인 번들 제작

1. 버전과 디렉터리 고정

반입 후 같은 태그를 재현할 수 있도록 버전을 변수로 고정한다. 파일명에도 버전과 아키텍처를 넣으면 여러 번들을 함께 보관할 때 혼동을 줄일 수 있다.

NETBOX_TAG="v4.6.5-5.0.2"
POSTGRES_TAG="18-alpine"
VALKEY_TAG="9.1-alpine"
BUNDLE_ID="netbox-airgap-${NETBOX_TAG}-rocky8-$(uname -m)"
BUNDLE_ROOT="/opt/${BUNDLE_ID}"

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

2. Podman RPM과 의존성 수집

dnf download --resolve만 사용하면 제작 서버에 이미 설치된 패키지를 건너뛸 수 있다. 폐쇄망 번들에서는 --alldeps를 함께 사용해야 한다. 제작 서버와 대상 서버의 활성 저장소가 다르면 서명 또는 의존성 문제가 생길 수 있으므로 저장소 목록도 매니페스트에 보관한다.

sudo dnf install -y dnf-plugins-core

sudo dnf download --resolve --alldeps   --destdir="${BUNDLE_ROOT}/rpms"   podman tar gzip openssl

sudo dnf repolist --enabled > "${BUNDLE_ROOT}/manifests/dnf-repolist.txt"
rpm -Kv "${BUNDLE_ROOT}"/rpms/*.rpm   > "${BUNDLE_ROOT}/manifests/rpm-signatures.txt"

3. 정확한 이미지 태그 Pull·Save

NetBox Docker는 NetBox 버전과 netbox-docker 지원 파일 버전이 결합된 태그를 제공한다. 운영에서는 정확한 태그를 사용하고, Pull 직후 다이제스트와 이미지 ID를 기록한다. podman save는 이미지 레이어와 태그를 보존하므로 컨테이너 파일시스템만 평탄화하는 podman export와 구분해야 한다.

podman pull "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"
podman pull "docker.io/postgres:${POSTGRES_TAG}"
podman pull "docker.io/valkey/valkey:${VALKEY_TAG}"

{
  podman image inspect --format 'netbox {{.Digest}} {{.Id}}'     "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"
  podman image inspect --format 'postgres {{.Digest}} {{.Id}}'     "docker.io/postgres:${POSTGRES_TAG}"
  podman image inspect --format 'valkey {{.Digest}} {{.Id}}'     "docker.io/valkey/valkey:${VALKEY_TAG}"
} > "${BUNDLE_ROOT}/manifests/image-digests.txt"

podman save --format oci-archive   -o "${BUNDLE_ROOT}/images/netbox.tar"   "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"
podman save --format oci-archive   -o "${BUNDLE_ROOT}/images/postgres.tar"   "docker.io/postgres:${POSTGRES_TAG}"
podman save --format oci-archive   -o "${BUNDLE_ROOT}/images/valkey.tar"   "docker.io/valkey/valkey:${VALKEY_TAG}"

4. 기본 비밀번호 없이 환경 파일 생성

예제 비밀번호를 그대로 게시하거나 재사용하면 안 된다. 아래 명령은 온라인 제작 시점에 난수를 생성하고 환경 파일 권한을 600으로 제한한다. ALLOWED_HOSTS의 주소와 이름은 실제 폐쇄망 환경에 맞게 바꾼다.

umask 077

DB_PASSWORD="$(openssl rand -hex 24)"
VALKEY_PASSWORD="$(openssl rand -hex 24)"
VALKEY_CACHE_PASSWORD="$(openssl rand -hex 24)"
ADMIN_PASSWORD="$(openssl rand -hex 18)"
API_TOKEN_PEPPER_1="$(openssl rand -hex 32)"
SECRET_KEY="$(podman run --rm   "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"   python /opt/netbox/netbox/generate_secret_key.py)"

cat > "${BUNDLE_ROOT}/env/postgres.env" << EOF
POSTGRES_DB=netbox
POSTGRES_USER=netbox
POSTGRES_PASSWORD=${DB_PASSWORD}
EOF

cat > "${BUNDLE_ROOT}/env/valkey.env" << EOF
VALKEY_PASSWORD=${VALKEY_PASSWORD}
EOF

cat > "${BUNDLE_ROOT}/env/valkey-cache.env" << EOF
VALKEY_PASSWORD=${VALKEY_CACHE_PASSWORD}
EOF

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

REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_DATABASE=0
REDIS_PASSWORD=${VALKEY_PASSWORD}
REDIS_SSL=false

REDIS_CACHE_HOST=127.0.0.1
REDIS_CACHE_PORT=6380
REDIS_CACHE_DATABASE=1
REDIS_CACHE_PASSWORD=${VALKEY_CACHE_PASSWORD}
REDIS_CACHE_SSL=false

SECRET_KEY=${SECRET_KEY}
API_TOKEN_PEPPER_1=${API_TOKEN_PEPPER_1}
ALLOWED_HOSTS=netbox.internal 10.20.30.40 localhost
TIME_ZONE=Asia/Seoul
LOGIN_REQUIRED=true
ISOLATED_DEPLOYMENT=true
CENSUS_REPORTING_ENABLED=false
COPILOT_ENABLED=false

SKIP_SUPERUSER=false
SUPERUSER_NAME=admin
SUPERUSER_EMAIL=netbox-admin@example.internal
SUPERUSER_PASSWORD=${ADMIN_PASSWORD}
EOF

chmod 600 "${BUNDLE_ROOT}"/env/*
printf 'admin password: %s
' "${ADMIN_PASSWORD}"   > "${BUNDLE_ROOT}/env/initial-admin-password.txt"
chmod 600 "${BUNDLE_ROOT}/env/initial-admin-password.txt"

최초 로그인 후에는 관리자 비밀번호를 변경하고 netbox.env에서 SUPERUSER_PASSWORD를 제거한 뒤 SKIP_SUPERUSER=true로 바꾸는 것이 안전하다. 공식 이미지의 변수 이름은 SUPERUSER_USERNAME이 아니라 SUPERUSER_NAME이다.

5. 폐쇄망 NetBox 구축 기동 스크립트

PostgreSQL과 두 Valkey가 준비된 것을 확인한 뒤 NetBox 웹과 worker를 시작한다. 공식 구성과 맞추기 위해 웹과 worker는 netbox:root 사용자로 실행하고, worker에서는 슈퍼유저 생성을 건너뛴다.

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

NETBOX_TAG="v4.6.5-5.0.2"
POSTGRES_TAG="18-alpine"
VALKEY_TAG="9.1-alpine"
BUNDLE_ROOT="/opt/netbox-airgap-${NETBOX_TAG}-rocky8-$(uname -m)"

NETBOX_ENV="${BUNDLE_ROOT}/env/netbox.env"
PG_ENV="${BUNDLE_ROOT}/env/postgres.env"
VALKEY_ENV="${BUNDLE_ROOT}/env/valkey.env"
VALKEY_CACHE_ENV="${BUNDLE_ROOT}/env/valkey-cache.env"

for file in "${NETBOX_ENV}" "${PG_ENV}" "${VALKEY_ENV}" "${VALKEY_CACHE_ENV}"; do
  [[ -r "${file}" ]] || { echo "[ERROR] missing ${file}" >&2; exit 1; }
done

if ! podman pod exists netbox-pod; then
  podman pod create --name netbox-pod -p 8000:8080
fi

for volume in netbox-postgres netbox-valkey-data netbox-valkey-cache-data               netbox-media-files netbox-reports-files netbox-scripts-files; do
  podman volume inspect "${volume}" >/dev/null 2>&1 || podman volume create "${volume}"
done

if ! podman container exists netbox-postgres; then
  podman run -d --name netbox-postgres --pod netbox-pod     --env-file "${PG_ENV}"     -v netbox-postgres:/var/lib/postgresql     "docker.io/postgres:${POSTGRES_TAG}"
fi

if ! podman container exists netbox-valkey; then
  podman run -d --name netbox-valkey --pod netbox-pod     --env-file "${VALKEY_ENV}"     -v netbox-valkey-data:/data     "docker.io/valkey/valkey:${VALKEY_TAG}"     sh -c 'valkey-server --appendonly yes --port 6379 --requirepass "$VALKEY_PASSWORD"'
fi

if ! podman container exists netbox-valkey-cache; then
  podman run -d --name netbox-valkey-cache --pod netbox-pod     --env-file "${VALKEY_CACHE_ENV}"     -v netbox-valkey-cache-data:/data     "docker.io/valkey/valkey:${VALKEY_TAG}"     sh -c 'valkey-server --port 6380 --requirepass "$VALKEY_PASSWORD"'
fi

dependencies_ready=0
for attempt in $(seq 1 90); do
  if podman exec netbox-postgres sh -c        'pg_isready -q -t 2 -d "$POSTGRES_DB" -U "$POSTGRES_USER"'     && podman exec netbox-valkey sh -c        'valkey-cli --pass "$VALKEY_PASSWORD" -p 6379 ping 2>/dev/null | grep -qx PONG'     && podman exec netbox-valkey-cache sh -c        'valkey-cli --pass "$VALKEY_PASSWORD" -p 6380 ping 2>/dev/null | grep -qx PONG'; then
    dependencies_ready=1
    break
  fi
  sleep 2
done

[[ "${dependencies_ready}" -eq 1 ]] || {
  echo "[ERROR] PostgreSQL or Valkey did not become ready" >&2
  exit 1
}

if ! podman container exists netbox; then
  podman run -d --name netbox --pod netbox-pod     --user netbox:root     --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

netbox_ready=0
for attempt in $(seq 1 120); do
  if podman exec netbox curl -fsS http://127.0.0.1:8080/login/ >/dev/null 2>&1; then
    netbox_ready=1
    break
  fi
  sleep 2
done

[[ "${netbox_ready}" -eq 1 ]] || {
  echo "[ERROR] NetBox did not become ready" >&2
  podman logs --tail 100 netbox >&2
  exit 1
}

if ! podman container exists netbox-worker; then
  podman run -d --name netbox-worker --pod netbox-pod     --user netbox:root     --env-file "${NETBOX_ENV}"     -e SKIP_SUPERUSER=true     "docker.io/netboxcommunity/netbox:${NETBOX_TAG}"     /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py rqworker
fi

podman pod ps
podman ps --pod
echo "NetBox: http://<server-ip>:8000"
SCRIPT

chmod 700 "${BUNDLE_ROOT}/scripts/run-netbox-pod.sh"

6. 데이터 보존형 정지·초기화 스크립트

기존 글처럼 이름에 postgresredis가 들어간 모든 컨테이너와 볼륨을 지우면 동일 서버의 다른 서비스 데이터가 삭제될 수 있다. 아래 스크립트는 정확한 NetBox 리소스만 대상으로 하며, 기본 실행에서는 데이터 볼륨을 보존한다.

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

mode="${1:-keep-data}"

podman pod rm -f netbox-pod 2>/dev/null || true
podman rm -f netbox netbox-worker netbox-postgres   netbox-valkey netbox-valkey-cache 2>/dev/null || true

if [[ "${mode}" == "--delete-data" ]]; then
  read -r -p '데이터를 완전히 삭제하려면 DELETE-NETBOX-DATA 입력: ' answer
  [[ "${answer}" == "DELETE-NETBOX-DATA" ]] || {
    echo "취소했습니다."
    exit 1
  }

  for volume in netbox-postgres netbox-valkey-data netbox-valkey-cache-data                 netbox-media-files netbox-reports-files netbox-scripts-files; do
    podman volume rm -f "${volume}" 2>/dev/null || true
  done
else
  echo "컨테이너만 제거했습니다. 데이터 볼륨은 보존됩니다."
fi
SCRIPT

chmod 700 "${BUNDLE_ROOT}/scripts/reset-netbox-pod.sh"

7. SHA-256 매니페스트와 압축 파일 생성

chmod 600 "${BUNDLE_ROOT}"/env/*

(
  cd "${BUNDLE_ROOT}"
  find rpms images env scripts manifests -type f -print0     | sort -z     | xargs -0 sha256sum > SHA256SUMS
)

cd /opt
sudo tar --xattrs --selinux -czf "${BUNDLE_ID}.tar.gz" "${BUNDLE_ID}"
sudo sha256sum "${BUNDLE_ID}.tar.gz" > "${BUNDLE_ID}.tar.gz.sha256"

폐쇄망 NetBox 구축: 오프라인 설치

1. 압축 파일과 내부 파일 무결성 검증

압축을 풀기 전에 외부 SHA-256 값을 확인하고, 전개 후에는 번들 내부 매니페스트를 검증한다. 하나라도 실패하면 설치하지 말고 반입 매체와 원본 번들을 다시 확인한다.

cd /opt
sudo sha256sum -c netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64.tar.gz.sha256
sudo tar --xattrs --selinux -xzf netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64.tar.gz

cd /opt/netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64
sudo sha256sum -c SHA256SUMS
sudo chown -R root:root .
sudo chmod 600 env/*

2. 외부 저장소 없이 Podman 설치

cd /opt/netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64
sudo dnf install -y --disablerepo='*' ./rpms/*.rpm
sudo podman --version

의존성 오류가 발생하면 폐쇄망에서 임의 RPM을 추가하지 말고, 온라인 제작 서버의 OS·아키텍처·활성 저장소가 대상 서버와 같은지 확인한 뒤 번들을 다시 만든다.

3. OCI 이미지 로드와 태그 확인

cd /opt/netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64

sudo podman load -i images/netbox.tar
sudo podman load -i images/postgres.tar
sudo podman load -i images/valkey.tar

sudo podman images --digests   | grep -E 'netboxcommunity/netbox|postgres|valkey/valkey'
cat manifests/image-digests.txt

로드 결과가 매니페스트와 다르면 기동하지 않는다. rootless로 로드한 이미지는 sudo podman에서 보이지 않으므로 로드와 실행 사용자를 일치시켜야 한다.

4. 방화벽 제한 후 최초 기동

예시는 관리망 10.20.0.0/16에서만 TCP 8000 접근을 허용한다. 실제 관리망 대역으로 수정한다. 방화벽을 먼저 구성하고 컨테이너를 기동하면 네트워크 재적용 문제를 줄일 수 있다.

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.20.0.0/16" port protocol="tcp" port="8000" accept'
sudo firewall-cmd --reload

cd /opt/netbox-airgap-v4.6.5-5.0.2-rocky8-x86_64
sudo ./scripts/run-netbox-pod.sh
curl -fsS http://127.0.0.1:8000/login/ -o /dev/null
sudo podman pod ps
sudo podman ps --pod

브라우저에서는 http://<폐쇄망 서버 IP>:8000으로 접속한다. 장기 운영에서는 8000 포트를 넓게 공개하지 말고, 내부 리버스 프록시와 TLS를 적용하는 편이 안전하다.

재부팅 후 자동 시작 구성

Rocky Linux 8.10 저장소의 Podman에서는 생성된 systemd 단위를 사용할 수 있다. --new 결과는 최선 노력 방식으로 생성되므로 반드시 파일 내용을 검토한 뒤 설치한다. Podman 5 계열에서는 이 명령이 사용 중단 예정이므로 신규 플랫폼은 Quadlet을 우선 검토한다.

unit_dir="$(mktemp -d)"
cd "${unit_dir}"
sudo podman generate systemd --new --files --name netbox-pod

sudo install -m 0644 ./*.service /etc/systemd/system/
sudo restorecon -Rv /etc/systemd/system

sudo podman pod rm -f netbox-pod
sudo systemctl daemon-reload
sudo systemctl enable --now pod-netbox-pod.service
sudo systemctl status pod-netbox-pod.service --no-pager

폐쇄망 NetBox 구축 보안 점검

  • ALLOWED_HOSTS=*를 사용하지 않고 실제 FQDN·IP와 localhost만 지정한다.
  • 예제 기본 비밀번호를 사용하지 않고 난수를 생성하며, 환경 파일과 백업 파일 권한을 600으로 제한한다.
  • 최초 로그인 후 관리자 비밀번호를 변경하고 환경 파일에서 초기 슈퍼유저 비밀번호를 제거한다.
  • 관리망에서만 8000 포트에 접근하도록 방화벽을 제한하고 가능하면 내부 TLS 프록시를 사용한다.
  • 이미지 태그뿐 아니라 다이제스트와 전체 번들의 SHA-256 값을 승인 기록에 남긴다.
  • 초기화 스크립트는 정확한 NetBox 리소스만 삭제하며 전역 prune를 자동 실행하지 않는다.

폐쇄망 NetBox 구축 상태 검증과 장애 대응

기본 상태와 로그 확인

sudo podman pod ps
sudo podman ps -a --pod

sudo podman logs --tail 100 netbox
sudo podman logs --tail 100 netbox-worker
sudo podman logs --tail 100 netbox-postgres
sudo podman logs --tail 100 netbox-valkey
sudo podman logs --tail 100 netbox-valkey-cache

sudo podman exec netbox   /opt/netbox/venv/bin/python /opt/netbox/netbox/manage.py version

로그 때문에 루트 파일시스템이 가득 찬 경우에는 컨테이너를 무작정 지우지 말고 No space left on device 진단 순서에 따라 블록·inode·삭제된 열린 파일을 먼저 구분한다.

자주 발생하는 오류와 원인

증상 우선 확인 해결 방향
DB 대기 후 NetBox 종료 PostgreSQL 로그와 DB_* 같은 Pod에서 127.0.0.1:5432인지 확인
400 Bad Request ALLOWED_HOSTS 실제 접속 FQDN·IP를 공백으로 구분해 추가
초기 admin 로그인 실패 SUPERUSER_NAME 변수명과 최초 기동 로그 확인
sudo에서 이미지가 안 보임 rootless/rootful 혼용 sudo podman load로 다시 로드
방화벽 reload 후 접속 불가 Podman 네트워크 규칙 sudo podman network reload --all 실행
로컬 RPM 의존성 오류 OS·아키텍처·저장소 동일 조건에서 --alldeps로 번들 재생성
sudo podman exec netbox-postgres sh -c   'pg_isready -d "$POSTGRES_DB" -U "$POSTGRES_USER"'

sudo podman exec netbox-valkey sh -c   'valkey-cli --pass "$VALKEY_PASSWORD" -p 6379 ping'

sudo podman network reload --all

마이그레이션은 NetBox 컨테이너 시작 과정에서 수행된다. 수동 manage.py migrate는 데이터베이스 백업과 이미지 버전 호환성을 확인한 뒤에만 마지막 수단으로 실행해야 한다.

백업과 복구

업그레이드나 재배포 전에 PostgreSQL 덤프와 media 볼륨을 함께 백업한다. Redis·Valkey는 작업 큐와 캐시이므로 핵심 원본 데이터는 PostgreSQL과 media이지만, 조직의 복구 목표에 따라 scripts와 reports 볼륨도 보관한다.

BACKUP_DIR="/var/backups/netbox/$(date +%F-%H%M%S)"
sudo install -d -m 0700 "${BACKUP_DIR}"

sudo podman exec netbox-postgres   pg_dump -U netbox -d netbox -Fc   | sudo tee "${BACKUP_DIR}/netbox.dump" >/dev/null

sudo podman volume export   --output "${BACKUP_DIR}/netbox-media-files.tar"   netbox-media-files

sudo sha256sum "${BACKUP_DIR}"/*   | sudo tee "${BACKUP_DIR}/SHA256SUMS"

백업 파일 생성만으로는 충분하지 않는다. 별도 테스트 서버에서 PostgreSQL 복원과 첨부 파일 접근을 정기적으로 검증해야 한다.

자주 묻는 질문

폐쇄망 NetBox 구축에 Pod를 사용하는 이유는?

Pod 안의 컨테이너가 네트워크 네임스페이스를 공유해 DB와 Valkey를 127.0.0.1로 연결할 수 있고 외부 공개 포트를 한곳에서 관리하기 쉽기 때문이다. 다만 리소스 격리와 독립 확장이 더 중요하면 별도 Pod 또는 오케스트레이터 구성을 검토해야 한다.

폐쇄망 NetBox 구축용 RPM 제작 서버 조건은?

대상 서버와 같은 Rocky Linux 8.10, 같은 CPU 아키텍처, 같은 활성 저장소 조건이 가장 안전하다. 제작 서버에 이미 설치된 의존성도 포함하도록 --alldeps를 사용한다.

latest 태그를 사용해도 되나요?

권장하지 않는다. 같은 이름이 다른 이미지로 이동할 수 있어 승인한 번들을 재현하기 어렵다. 정확한 버전 태그와 다이제스트를 함께 기록하고, 업그레이드는 새 번들로 분리해 검증한다.

정리

안전한 폐쇄망 NetBox 구축은 파일 복사보다 버전 고정, 동일한 RPM 저장소 조건, 이미지 다이제스트와 SHA-256 검증, 비밀정보 관리, 정확한 삭제 범위, 백업 복구 시험이 핵심이다. 이 순서를 지키면 인터넷이 없는 Rocky Linux 환경에서도 Podman 기반 NetBox를 재현 가능하게 운영할 수 있다.

공식 참고 문서