인터넷이 차단된 RHEL 리눅스 서버에 Docker 엔진 설치하기

일반적으로 운영서버에서는 직접 인터넷을 접속할 수 없도록 방화벽이 설정되어 있을 겁니다. 이런 환경에서 새로운 패키지를 설치하는 건 조금 번거로운 일이 되겠죠. 최근 회사에서 신규 시스템을 구축하는데 도커를 사용하자는 의견이 있어서 이 글의 제목처럼 인터넷이 차단된 RHEL 리눅스 서버(VERSION_ID=”7.9″)에 Docker 엔진 설치해 보겠습니다.

  1. Docker 다운로드 사이트에서 docker 엔진 설치에 필요한 패키지를 개인PC로 다운로드합니다.
  2. 지금부터는 리눅스에 로그인하여 작업을 해야 합니다. 먼저 로컬 저장소(Local Repository) 생성에 필요한 패키지(createrepo 패키지)와 의존성 패키지가 설치되어 있는지 확인해 보겠습니다. 저는 다행히 모두 설치되어 있네요.
    -- 필수 의존성 패키지가 설치되어 있는지 확인해 봅니다.
    $ rpm -q createrepo deltarpm python-deltarpm libxml2-python
    createrepo-0.9.9-28.el7.noarch
    deltarpm-3.6-3.el7.x86_64
    python-deltarpm-3.6-3.el7.x86_64
    libxml2-python-2.9.1-6.el7_9.9.x86_64
    
    -- 의존성 패키지가 이미 다 설치되어 있다면 Nothing to do 라는 메시지가 출력됩니다.
    $ yum localinstall createrepo* --assumeno
    Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-manager
    This system is not registered with an entitlement server. You can use subscription-manager to register.
    Skipping: createrepo*, filename does not end in .rpm.
    Nothing to do
    
  3. 다운로드한 docker 관련 패키지를 업로드할 디렉토리를 생성하고, FileZilla 등 FTP 프로그램을 통해 생성한 디렉토리로 업로드합니다.
    -- root 사용자로 접속할 수 없는 경우가 있기 때문에 접근모드를 "777"로 설정했습니다.
    -- 설치가 끝난 다음에 접근모드를 "755"로 변경하시면 됩니다.
    $ mkdir -p -m 777 /opt/docker-repo
    
    -- 파일 업로드 후 확인
    $ ls -l /opt/docker-repo
    total 100368
    -rw-rw-r-- 1 pmmhadm pmmhadm 37045876 Feb 11 09:16 containerd.io-1.6.33-3.1.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm    39712 Feb 11 09:16 container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm 14280912 Feb 11 09:16 docker-buildx-plugin-0.14.1-1.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm 28596976 Feb 11 09:16 docker-ce-26.1.4-1.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm 15445372 Feb 11 09:16 docker-ce-cli-26.1.4-1.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm  9840840 Feb 11 09:16 docker-ce-rootless-extras-26.1.4-1-1.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm    29392 Feb 11 09:16 docker-ce-selinux-17.03.3.ce-1.el7.noarch.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm  7367636 Feb 11 09:16 docker-compose-plugin-2.6.0-3.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm    82660 Feb 11 09:16 fuse3-libs-3.6.1-4.el7.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm    54692 Feb 11 09:16 fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm
    -rw-rw-r-- 1 pmmhadm pmmhadm    82348 Feb 11 09:16 slirp4netns-0.4.3-4.el7_8.x86_64.rpm
    
  4. createrepo 명령어를 사용해서 로컬 저장소(Local Repository)를 생성하고 메타데이터를 빌드합니다.
    $ createrepo /opt/docker-repo/
    Spawning worker 0 with 6 pkgs
    Spawning worker 1 with 5 pkgs
    Workers Finished
    Saving Primary metadata
    Saving file lists metadata
    Saving other metadata
    Generating sqlite DBs
    Sqlite DBs complete
    
    -- /opt/docker-repo/repodata/ 디렉토리가 생성되고 해당 디렉토리에 메타데이터가 저장됩니다.
    # ls -l /opt/docker-repo/repodata/
    total 32
    -rw-r--r-- 1 root root 1828 Feb 11 10:48 1d24f9effad4df4b734f745c2946bf56a71526e69b1c8cb2cda70389c715ba39-filelists.xml.gz
    -rw-r--r-- 1 root root 2627 Feb 11 10:48 7331dde02285f45e819a039cd16dc464ecaf44fff721a6ea7a96267ec520b5ac-primary.xml.gz
    -rw-r--r-- 1 root root  994 Feb 11 10:48 8d2b6168da25393940f08f4b3f4f3bcb5bcb9f33ca0cf0a1b374b191fe86270c-other.xml.gz
    -rw-r--r-- 1 root root 3153 Feb 11 10:48 8ef8ddfaffd6fccafc42531c3b1e7c0af41b6473ef4c23f6408248cd9a764346-filelists.sqlite.bz2
    -rw-r--r-- 1 root root 5565 Feb 11 10:48 98f56fc031e853546cb61a0ff42b61cc880521bef75fb4e1887d04c342fcc5dc-primary.sqlite.bz2
    -rw-r--r-- 1 root root 1731 Feb 11 10:48 d16128717fe8abfe46060dd9081305cfbbbd804d50463116180235b660e63c03-other.sqlite.bz2
    -rw-r--r-- 1 root root 2972 Feb 11 10:48 repomd.xml
    
  5. Repo 설정 파일을 생성하고, 로컬 저장소를 등록합니다. 여기서 잠깐! Docker사용해서 NextCloud를 설치할 때는 GPG키가 필요했지만, 여기서는 필요가 없습니다. 왜냐하면 gpgcheck=0, 즉 gpgcheck를 비활성화했기 때문입니다.
    $ vi /etc/yum.repos.d/local.repo
    [local-docker]
    name=Local Docker Repository
    baseurl=file:///opt/docker-repo
    enabled=1
    gpgcheck=0
    
    -- 기존 yum 캐시 삭제
    $ yum clean all; yum makecache
    
    -- 저장소 목록에 'local-docker'가 뜨는지 확인합니다. 11개의 패키지를 다운로드한 결과와 동일합니다.
    $ yum repolist | grep local-docker
    local-docker                   Local Docker Repository                      11
    
  6. Docker 공식 사이트의 설치 가이드를 참고하여 Docker 설치를 진행하겠습니다.
    -- old version Docker의 설치 여부를 확인합니다.
    $ rpm -qa | grep docker
    
    -- old version Docker가 설치되어 있다면 아래와 같이 삭제합니다.
    $ yum remove -y docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
    
    -- Docker 패키지가 저장되어 있는 로컬 저장소(local-docker)를 지정하고 Docker 패키지를 설치합니다.
    $ yum install -y --enablerepo='local-docker' \
    docker-ce \
    docker-ce-cli \
    containerd.io \
    docker-buildx-plugin \
    docker-compose-plugin \
    docker-ce-selinux
    
  7. 도커 서비스를 시작하고 상태 및 버전을 확인해 봅니다.
    $ systemctl enable --now docker
    $ systemctl status docker
    $ docker version
    
  8. 마지막으로 Docker 이미지(httpd 서비스 제공)를 만든 후, 설치/실행/접속까지 해 보겠습니다. Docker CLI 명령어 사용법은 여기를 참고하세요.
    1. 베이스 이미지를 빌드하는 과정입니다. 베이스 이미지는 기초적인 리눅스 환경을 미리 구성하여 사용자가 이미지 빌드 시 별도의 작업없이 OS 구성 요소를 이미지 내부에 포함시킬 수 있습니다. 베이스 이미지를 빌드하기 위해서는 리눅스 설치 ISO파일이 필요합니다. 현재 사용하고 있는 RHEL 설치 ISO파일이 마운팅되어 있는지 확인합니다. 베이스 이미지로 Ubuntu, CentOS, 혹은 훨씬 가벼운 Alpine Linux를 사용해도 아무 문제 없이 잘 돌아갑니다.
      -- 저는 /run/media/root/RHEL-7.7 Server.x86_64 경로에 마운팅되어 있습니다.
      -- /dev/sr0 디바이스에 ISO파일을 Attach하고 마운팅해야 합니다. 
      $ df -hT | grep /dev/sr0
      /dev/sr0                                iso9660   4.2G  4.2G     0 100% /run/media/root/RHEL-7.7 Server.x86_64
      
    2. ISO파일을 로컬 저장소에 추가 등록할 수도 있으나, 도커 이미지 빌드 시 사용하기 위해서 복사 후 저장소에 등록하겠습니다.
      $ mkdir /opt/iso-repo
      $ cp -r /run/media/root/RHEL-7.7\ Server.x86_64/Packages /opt/iso-repo/
      $ cp -r /run/media/root/RHEL-7.7\ Server.x86_64/repodata /opt/iso-repo/
      $ vi /etc/yum.repos.d/local.repo
      [local-docker]
      name=Local Docker Repository
      baseurl=file:///opt/docker-repo
      enabled=1
      gpgcheck=0
      
      [rhel-iso]
      name=RHEL 7.7 ISO Repository
      baseurl=file:///opt/iso-repo
      enabled=1
      gpgcheck=0
      
      $ yum clean all >/dev/null; yum makecache >/dev/null; yum repolist | grep rhel-iso
      rhel-iso                       RHEL 7.7 ISO Repository                    5,229
      
    3. ISO 파일을 이용해서 RHEL 베이스 이미지를 생성합니다.
      -- ISO파일에서 추출한 OS 파일들을 담을 임시 디렉토리 생성
      $ mkdir -p /tmp/rhel-root
      
      -- ISO 내용물을 기반으로 최소 OS 설치 (Rootfs 생성)
      $ yum install -y --installroot=/tmp/rhel-root \
      --releasever=7.7 \
      --disablerepo=* \
      --enablerepo=rhel-iso \
      bash yum coreutils
      
      -- /tmp/rhel-root/ 디렉토리에 RHEL7.7의 루트 파일시스템(rootfs)이 설치된 것을 확인합니다.
      $ ls -l /tmp/rhel-root/
      total 8
      lrwxrwxrwx  1 root root    7 Feb 11 14:52 bin -> usr/bin
      dr-xr-xr-x  2 root root    6 Dec 15  2017 boot
      drwxr-xr-x  2 root root   18 Feb 11 14:52 dev
      drwxr-xr-x 33 root root 4096 Feb 11 14:52 etc
      drwxr-xr-x  2 root root    6 Dec 15  2017 home
      lrwxrwxrwx  1 root root    7 Feb 11 14:52 lib -> usr/lib
      lrwxrwxrwx  1 root root    9 Feb 11 14:52 lib64 -> usr/lib64
      drwxr-xr-x  2 root root    6 Dec 15  2017 media
      drwxr-xr-x  2 root root    6 Dec 15  2017 mnt
      drwxr-xr-x  2 root root    6 Dec 15  2017 opt
      dr-xr-xr-x  2 root root    6 Dec 15  2017 proc
      dr-xr-x---  2 root root    6 Dec 15  2017 root
      drwxr-xr-x  3 root root   19 Feb 11 14:52 run
      lrwxrwxrwx  1 root root    8 Feb 11 14:52 sbin -> usr/sbin
      drwxr-xr-x  2 root root    6 Dec 15  2017 srv
      dr-xr-xr-x  2 root root    6 Dec 15  2017 sys
      drwxrwxrwt  2 root root    6 Dec 15  2017 tmp
      drwxr-xr-x 13 root root  155 Feb 11 14:52 usr
      drwxr-xr-x 18 root root  238 Feb 11 14:52 var
      
    4. RHEL7.7 루트 파일시스템의 도커 이미지를 생성합니다.
      $ tar -C /tmp/rhel-root -c . | docker import - rhel7:7.7
      sha256:16f2c5f23349c2e4c12c5dbf4f3d8c18cab410cda8a1057372cdbac367273e77
      
      -- rhel7:7.7 이미지가 도커에 생성된 것을 확인할 수 있습니다.
      $ docker image ls
      REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
      rhel7        7.7       16f2c5f23349   24 seconds ago   313MB
      
    5. 사용자 이미지를 빌드하는 과정입니다. 빌드 작업용 디렉토리 생성하고 이동합니다: 이미지에 들어갈 파일들을 한 곳에 모으기 위한 공간입니다.
      $ mkdir -p /tmp/mydocker-build ; cd !$
      
    6. /opt/iso-repo 디렉토리와 /etc/yum.repos.d/local.repo 파일을 빌드 작업용 디렉토리로 복사합니다.
      $ cp -r /opt/iso-repo .
      $ cp /etc/yum.repos.d/local.repo .
      
    7. /tmp/mydocker-build/Dockerfile를 작성합니다.
      $ vi Dockerfile
      # 1. 기반이 될 이미지 (로컬 저장소에 이미 있는 이미지 사용 권장)
      FROM rhel7:7.7
      
      # 2. 만든 사람 정보
      LABEL maintainer="username@yesxyz.kr"
      
      # 3. 호스트의 local.repo 파일을 도커 내부의 /etc/yum.repos.d/ 디렉토리로 복사합니다.
      COPY local.repo /etc/yum.repos.d/
      
      # 4. 빌드 마운트를 사용하여 호스트의 ./iso-repo 경로를 도커 내부의 /opt/iso-repo에 연결
      RUN --mount=type=bind,source=./iso-repo,target=/opt/iso-repo \
          yum install -y httpd --disablerepo=* --enablerepo=iso-repo
      
      # 5. 설치 완료 후 복사된 파일 삭제 (선택 사항)
      RUN rm -f /etc/yum.repos.d/local.repo
      
      # 6. 컨테이너가 시작될 때 실행할 명령
      CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
      
    8. Dockerfile이 있는 위치에서 docker build 명령어를 실행하여 Docker image를 빌드합니다.
      -- -t (Tag부여, 이미지의 이름과 버전을 붙여주는 옵션)
      -- my-httpd-app (내가 만들 이미지의 이름)
      -- :1.0 (이미지의 버전 번호. 생략하면 자동으로 :latest가 붙습니다.)
      -- . (현재 디렉토리에 있는 Dockerfile을 사용하라)
      $ docker build -t my-httpd-app:1.0 .
      [+] Building 13.1s (9/9) FINISHED                                                                                                                 docker:default
       => [internal] load build definition from Dockerfile                                                                                                        0.0s
       => => transferring dockerfile: 815B                                                                                                                        0.0s
       => [internal] load metadata for docker.io/library/rhel7:7.7                                                                                                0.0s
       => [internal] load .dockerignore                                                                                                                           0.0s
       => => transferring context: 2B                                                                                                                             0.0s
       => [stage-0 1/4] FROM docker.io/library/rhel7:7.7                                                                                                          0.0s
       => [internal] load build context                                                                                                                           0.2s
       => => transferring context: 398.55kB                                                                                                                       0.1s
       => CACHED [stage-0 2/4] COPY local.repo /etc/yum.repos.d/                                                                                                  0.0s
       => [stage-0 3/4] RUN --mount=type=bind,source=./iso-repo,target=/opt/iso-repo     yum install -y httpd --disablerepo=* --enablerepo=rhel-iso              10.9s
       => [stage-0 4/4] RUN rm -f /etc/yum.repos.d/local.repo                                                                                                     0.3s 
       => exporting to image                                                                                                                                      1.6s 
       => => exporting layers                                                                                                                                     1.6s 
       => => writing image sha256:fd7774cc2db148f18623ce0178f1cb66cc1ed43a2afd943b45e4984b4ed5c7d6                                                                0.0s 
       => => naming to docker.io/library/my-httpd-app:1.0                                                                                                         0.0s
      
    9. 빌드가 성공적으로 끝나면 로컬 이미지 목록에서 확인합니다.
      $ docker image ls
      REPOSITORY     TAG       IMAGE ID       CREATED              SIZE
      my-httpd-app   1.0       fd7774cc2db1   3 minutes ago        481MB
      rhel7          7.7       16f2c5f23349   30 minutes ago       313MB
      
    10. 컨테이너를 실행하여 외부에서 http 접속하기
      -- -d (백그라운드 실행)
      -- -p 8080:80 (호스트 8080포트를 컨테이너 80포트로 연결)
      $ docker run -d -p 8080:80 --name my-web-server my-httpd-app:1.0
      
      -- 실행되고 있는 Docker Container 확인
      $ docker ps
      CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                   NAMES
      2dc443831c2f   my-httpd-app:1.0   "/usr/sbin/httpd -D …"   8 seconds ago   Up 7 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   my-web-server
      
      -- 8080 포트로 접속되는지 확인해 봅니다. 성공입니다.
      $ wget http://host_ip_address:8080
      --2026-02-11 16:54:39--  http://58.54.160.112:8080/
      Connecting to 58.54.160.112:8080... connected.
      HTTP request sent, awaiting response... 403 Forbidden
      2026-02-11 16:54:39 ERROR 403: Forbidden.
      
    11. 도커 컨테이너 내부로 들어가기 (bash 접속)
      -- -it (터미널 모드로 접속)
      -- bash (쉘 실행)
      $ docker exec -it my-web-server bash
      bash-4.2# 
      

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다