인터넷이 차단된 RHEL 리눅스 서버에 Docker 엔진 설치하기
일반적으로 운영서버에서는 직접 인터넷을 접속할 수 없도록 방화벽이 설정되어 있을 겁니다. 이런 환경에서 새로운 패키지를 설치하는 건 조금 번거로운 일이 되겠죠. 최근 회사에서 신규 시스템을 구축하는데 도커를 사용하자는 의견이 있어서 이 글의 제목처럼 인터넷이 차단된 RHEL 리눅스 서버(VERSION_ID=”7.9″)에 Docker 엔진 설치해 보겠습니다.
- Docker 다운로드 사이트에서 docker 엔진 설치에 필요한 패키지를 개인PC로 다운로드합니다.
- docker-ce(동일 버전-중요)
- docker-ce-cli(동일 버전-중요)
- docker-ce-rootless-extras(동일 버전-중요)
- docker-ce-selinux(SELinux를 적용하고 있다면 필수)
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
- docker-scan-plugin(선택)
- container-selinux(docker-ce 의존성 패키지)
- slirp4netns(docker-ce-rootless-extras 의존성 패키지)
- fuse-overlayfs(docker-ce-rootless-extras 의존성 패키지)
- libfuse3.so.3(FUSE_3.0)(64bit)(fuse-overlayfs 의존성 패키지)
- 지금부터는 리눅스에 로그인하여 작업을 해야 합니다. 먼저 로컬 저장소(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
- 다운로드한 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
- 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
- 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
- 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
- 도커 서비스를 시작하고 상태 및 버전을 확인해 봅니다.
$ systemctl enable --now docker $ systemctl status docker $ docker version
- 마지막으로 Docker 이미지(httpd 서비스 제공)를 만든 후, 설치/실행/접속까지 해 보겠습니다. Docker CLI 명령어 사용법은 여기를 참고하세요.
- 베이스 이미지를 빌드하는 과정입니다. 베이스 이미지는 기초적인 리눅스 환경을 미리 구성하여 사용자가 이미지 빌드 시 별도의 작업없이 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
- 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
- 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
- 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
- 사용자 이미지를 빌드하는 과정입니다. 빌드 작업용 디렉토리 생성하고 이동합니다: 이미지에 들어갈 파일들을 한 곳에 모으기 위한 공간입니다.
$ mkdir -p /tmp/mydocker-build ; cd !$
- /opt/iso-repo 디렉토리와 /etc/yum.repos.d/local.repo 파일을 빌드 작업용 디렉토리로 복사합니다.
$ cp -r /opt/iso-repo . $ cp /etc/yum.repos.d/local.repo .
- /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"] - 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
- 빌드가 성공적으로 끝나면 로컬 이미지 목록에서 확인합니다.
$ 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
- 컨테이너를 실행하여 외부에서 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.
- 도커 컨테이너 내부로 들어가기 (bash 접속)
-- -it (터미널 모드로 접속) -- bash (쉘 실행) $ docker exec -it my-web-server bash bash-4.2#
- 베이스 이미지를 빌드하는 과정입니다. 베이스 이미지는 기초적인 리눅스 환경을 미리 구성하여 사용자가 이미지 빌드 시 별도의 작업없이 OS 구성 요소를 이미지 내부에 포함시킬 수 있습니다. 베이스 이미지를 빌드하기 위해서는 리눅스 설치 ISO파일이 필요합니다. 현재 사용하고 있는 RHEL 설치 ISO파일이 마운팅되어 있는지 확인합니다. 베이스 이미지로 Ubuntu, CentOS, 혹은 훨씬 가벼운 Alpine Linux를 사용해도 아무 문제 없이 잘 돌아갑니다.
