- [Network | Docker] Apache, Docker Compose를 이용한 Reverse Proxy 구성2024년 07월 17일 18시 04분 55초에 업로드 된 글입니다.작성자: 이주여이
📢 해당 포스트는 Docker Compose를 사용하여 여러 컨테이너들을 하나의 서비스로 묶어 관리하고 호스트 PC에 설치된 httpd(Apache)를 통해 특정 도메인과 도커 컨테이너를 연결하는 과정을 설명합니다.
🛠️ 참고
Virtualbox - Oracle VM Virtualbox
Linux OS - Rocky Linux
HTTPD - Apache0. Docker Compose 개념
docker-compose.yml 파일을 사용해 하나의 가상 서버에서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너를 묶음으로 관리할 수 있다.
만약 Docker Compose를 사용하지 않는다면 컨테이너를 하나 하나씩 run 해야하는 번거러움이 있다. 하지만 Docker Compose를 사용하면 한번의 명령어로 설정 파일 안에 여러 개의 컨테이너들을 관리할 수 있다.(각 컨테이너들의 의존성, 네트워크, 볼륨 등등)
정말 편하긴 하더라.. 이제 docker run 안해도 된다!
1. Docker Compose 설치
# 도커 깃허브 저장소에서 Docker Compose 다운로드 [root@localhost ~]# curl -L https://github.com/docker/compose/releases/download/1.11.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 8052k 100 8052k 0 0 4269k 0 0:00:01 0:00:01 --:--:-- 6290k # 권한 부여 [root@localhost ~]# chmod +x /usr/local/bin/docker-compose # 버전 확인 [root@localhost ~]# docker-compose -v docker-compose version 1.11.0, build 6de1806
2. docker-compose.yml 생성
💡 하위 항목은 탭(Tab)이 아닌 2개의 공백으로 하위 항목을 구분한다.
version: "3.0" services: app5221: build: context: /home/user5221 dockerfile: Dockerfile container_name: app5221 ports: - "5221:80" volumes: - 5221:/home/download app5222: build: context: /home/user5222 dockerfile: Dockerfile container_name: app5222 ports: - "5222:80" volumes: - 5222:/home/download app5224: build: context: /home/user5224 dockerfile: Dockerfile container_name: app5224 ports: - "5224:80" volumes: - 5224:/home/download volumes: '5221': external: true '5222': external: true '5224': external: true
- version - Docker Compose 버전을 지정한다. 3.0 버전은 Docker Compose 1.10 및 Docker Engine 1.13.0 이상에서 사용된다.
- services - 생성될 컨테이너를 묶어놓은 단위로 services 아래에 생성할 컨테이너 서비스를 지정한다.
- app5221, app5222, app5224 - 생성될 서비스의 이름으로 각각의 서비스는 하나의 컨테이너를 나타낸다.
- build - build 아래에 하위 항목으로 빌드할 때 사용할 옵션을 지정한다.
- context
- Dockerfile이 있는 경로를 지정한다.
- 이전에 Dockerfile로 빌드 할 때
su - user5221
계정으로 접속해 루트 경로에서 Dockerfile과 app.jar을 두고 진행했었다. 현재 경로에서 dockerfile과 build 파일이 어디 있는지 적어주면 된다.
- dockerfile - Dockerfile 그대로 적어준다.
- context
- container_name - 컨테이너 명을 지정한다.
- ports
- 해당 컨테이너로 접속할 포트를 지정한다.
- 5221 포트로 요청 시 컨테이너 내부의 80 포트로 전달한다.
-
FROM openjdk:17-jdk-alpine ARG JAR_FILE=*.jar ADD ${JAR_FILE} app.jar EXPOSE 80 WORKDIR /home/user5221 VOLUME /home/download/ ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"]
- 조금 더 쉽게 이해하기 위해 위의 dockerfile을 보자. dockerfile에 EXPOSE를 80으로 지정했다. 이것은 도커 컨테이너 내부에 포트 번호를 80으로 지정한다는 뜻이다. 그리고 docker-compose.yml에서 지정한 ports 5221은 내가
도메인:5221
로 접근할 경우 5221 포트를 확인하고 도커 컨테이너 내부의 80 포트로 매핑해주는 것이다.
- volumes - 호스트와 컨테이너 간의 디렉토리 혹은 파일을 공유할 수 있는 볼륨을 지정한다.(볼륨이 없다면
docker volume create --name ${볼륨명 }
으로 만들면 된다) 왼쪽엔 내가 만들어놨던 도커 볼륨을 오른쪽엔 컨테이너 내에 파일이 저장될 경로를 적어주면 된다.
- services - 생성될 컨테이너를 묶어놓은 단위로 services 아래에 생성할 컨테이너 서비스를 지정한다.
- volumes
- 외부 볼륨을 설정한다.
- 5221 ~ 5224 - 볼륨명(참고로 숫자만 있다면 따옴표(’)로 감싸줘야 한다. 아니면 docker-compose.yml 실행 시 따옴표로 감싸라며 에러가 발생한다)
- external: true - docker-compose.yml에서 정의한 볼륨이 외부에 이미 존재하며 Docker Compose가 해당 볼륨을 새로 생성하지 않고 기존에 있던 볼륨을 사용할 수 있도록 지정한다.
3. httpd 수정
❓ 앞에 숫자가 있는 것은 vi 편집기에서 `:set number` 명령어로 넘버 라인을 표시했기 때문이다.
47 Listen 80 100 ServerName localhost:80 360 <VirtualHost *:80> 361 ServerName ljy.r-e.kr 362 ProxyPreserveHost On 363 ProxyPass / http://192.168.56.103:5221/ 364 ProxyPassReverse / http://192.168.56.103:5221/ 365 </VirtualHost> 366 367 <VirtualHost *:80> 368 ServerName replay.o-r.kr 369 ProxyPreserveHost On 370 ProxyPass / http://192.168.56.103:5222/ 371 ProxyPassReverse / http://192.168.56.103:5222/ 372 </VirtualHost> 373 374 <VirtualHost *:80> 375 ServerName ttoganjip.kro.kr 376 ProxyPreserveHost On 377 ProxyPass / http://192.168.56.103:5224/ 378 ProxyPassReverse / http://192.168.56.103:5224/ 379 </VirtualHost>
- Listen 80 - 호스트 PC의 포트 번호는 기본적으로 80이다. 어디서 사용하는 거 아니면 변경할 필요는 없다.
- ServerName localhost:80 - ServerName에 앞에 #로 주석 처리가 되어있을 경우 'systemctl restart httpd' 했을 때 에러가 발생하므로 주석을 풀어준다.
- <VirtualHost> - 가상 호스트를 설정하는 시작 태그
- * - 와일드 카드, 모든 IP에서 접근할 수 있다.
- 80 - 웹 브라우저에서 접근할 포트
- ServerName - 발급받은 도메인 주소를 적어주면 된다.
- ProxyPass
- 웹 서버가 받은 요청을 다른 서버로 전달한다.
- 간단하게 설명하면
ljy.r-e.kr
도메인으로 접근할 경우 포트 80은 http의 기본 포트이기 때문에 생략이 가능하다. 그리고 ProxyPass 옆에/
로 명시했기 때문에 ServerName 자체로 접근이 가능하다. 만약/
옆에/app1
과 같이 문자가 있을 경우http://ljy.r-e.kr/app1
까지 접근해줘야 192.xxx.xxx.xx.xxx:5221 로 매핑된다. /
우측의192.xxx.xx.xxx
는 호스트 PC(도커 컨테이너가 있는 가상 서버)의 IP 주소이며5221
은 위에 docker-compose.yml을 실행하며 생성된 도커 컨테이너의 포트 번호이다.
- ProxyPassReverse - ProxyPassReverse는 ProxyPass로 전달된 요청의 응답을 원래 요청한 URL(http://ljy.r-e.kr)로 반환한다.
4. docker-compose.yml 실행
[root@localhost ~]# docker-compose up -d Building app5221 Step 1/7 : FROM openjdk:17-jdk-alpine 17-jdk-alpine: Pulling from library/openjdk Digest: sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81 Status: Downloaded newer image for openjdk:17-jdk-alpine ---> 264c9bdce361 Step 2/7 : ARG JAR_FILE=*.jar ---> Running in d4e39d164dab ---> Removed intermediate container d4e39d164dab ---> 123f25dbf9ef Step 3/7 : ADD ${JAR_FILE} app.jar ---> 3c33b3c3ab69 Step 4/7 : EXPOSE 80 ---> Running in 2b4b2b2843d1 ---> Removed intermediate container 2b4b2b2843d1 ---> a5d5b704de06 Step 5/7 : WORKDIR /home/user5221 ---> Running in 2e3190589b51 ---> Removed intermediate container 2e3190589b51 ---> de8bdb8b89a9 Step 6/7 : VOLUME /home/download/ ---> Running in 8e8f719dee29 ---> Removed intermediate container 8e8f719dee29 ---> d1906f0955fd Step 7/7 : ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"] ---> Running in 76b283596830 ---> Removed intermediate container 76b283596830 ---> 45add8706680 Successfully built 45add8706680 Successfully tagged root_app5221:latest Step 1/7 : FROM openjdk:17-jdk-alpine ---> 264c9bdce361 Step 2/7 : ARG JAR_FILE=*.jar ---> Using cache ---> 123f25dbf9ef Step 3/7 : ADD ${JAR_FILE} app.jar ---> d82f9b2101cf Step 4/7 : EXPOSE 80 ---> Running in 5de73cff26e0 ---> Removed intermediate container 5de73cff26e0 ---> e882c553ce93 Step 5/7 : WORKDIR /home/user5222 ---> Running in 1e8354ca8a60 ---> Removed intermediate container 1e8354ca8a60 ---> 0f4aa1023a3f Step 6/7 : VOLUME /home/download/ ---> Running in e960781f165a ---> Removed intermediate container e960781f165a ---> 865d83bf6c09 Step 7/7 : ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"] ---> Running in 2b4961456f2e ---> Removed intermediate container 2b4961456f2e ---> 05a578f785fc Successfully built 05a578f785fc Successfully tagged root_app5222:latest Step 1/7 : FROM openjdk:17-jdk-alpine ---> 264c9bdce361 Step 2/7 : ARG JAR_FILE=*.jar ---> Using cache ---> 123f25dbf9ef Step 3/7 : ADD ${JAR_FILE} app.jar ---> 3320792a1923 Step 4/7 : EXPOSE 80 ---> Running in cebb9be1f1f7 ---> Removed intermediate container cebb9be1f1f7 ---> d236bab3f5ae Step 5/7 : WORKDIR /home/user5224 ---> Running in b569d6082ae4 ---> Removed intermediate container b569d6082ae4 ---> 717ddfe785e0 Step 6/7 : VOLUME /home/download/ ---> Running in afac756c4972 ---> Removed intermediate container afac756c4972 ---> b8509aceb6a7 Step 7/7 : ENTRYPOINT ["java","-jar","-Dspring.profiles.active=prod","/app.jar"] ---> Running in 85b6a4ae19c8 ---> Removed intermediate container 85b6a4ae19c8 ---> 27fa929132f9 Successfully built 27fa929132f9 Successfully tagged root_app5224:latest Creating app5221 Creating app5224 Creating app5222 Creating apache
그리고
docker ps
명령어를 통해 컨테이너가 정상적으로 띄워졌는지 확인해보자.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e4475ce40736 root_app5221 "java -jar -Dspring.…" 3 hours ago Up 3 hours 0.0.0.0:5221->80/tcp, :::5221->80/tcp app5221 f344f94e5267 root_app5222 "java -jar -Dspring.…" 3 hours ago Up 3 hours 0.0.0.0:5222->80/tcp, :::5222->80/tcp app5222 bb9858deaf5f root_app5224 "java -jar -Dspring.…" 3 hours ago Up 3 hours 0.0.0.0:5224->80/tcp, :::5224->80/tcp app5224 925df5c890d9 mariadb "docker-entrypoint.s…" 8 days ago Up 2 days 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp mariadb
5. 포트 포워딩 및 방화벽 포트 등록
1. 공유기 포트 포워딩
80 포트는 가상 서버의 httpd 기본 포트(변경하지 않았으므로 이 포트를 사용했다) 그리고 5221 ~ 5229까지 되어있는 것은 위에서 5221, 5222, 5224와 같이 도커 컨테이너 접근 시 사용하는 포트 번호를 미리 설정해놓은 것이다.
2. 가상 머신 포트 포워딩
내가 포스팅한 네트워크 관련 글에는 죄다 이 캡처가 들어가있는 것 같은데.. 여튼 이렇게 외부에서 들어오는 요청을 받을 수 있게 설정해준다. 외부에서 80 포트로 들어오면 내부의 80 포트(http 기본 포트)로 연결시킨다. 만약 httpd.conf에서 포트를 8080 뭐 이런 식으로 잡았다면 80, 8080으로 설정해야겠지..
3. 방화벽 포트 등록
80 포트를 받을 수 있게 firewall을 통해 포트를 등록한다.
[root@localhost ~]# firewall-cmd --permanent --add-port=80/tcp [root@localhost ~]# firewall-cmd --reload [root@localhost ~]# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: enp0s3 enp0s8 sources: services: cockpit dhcpv6-client ssh ports: 30000/tcp 80/tcp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
이렇게 등록되어 있으면 된다.
6. 도메인 등록
나는 무료로 도메인을 발급해주는 내도메인.한국을 사용하고 있다.
궁금하면 아래 이전 포스팅 링크를 통해 발급받는 방법을 확인할 수 있다.
그리고 IP 연결할 때 뒤에 포트 번호는 붙이지 않는다.
공인 IP로 해당 도메인에 접근했을 때 위에 httpd.conf에서 지정한 5221 포트로 매핑된다.
7. 확인
짠~
'Network > Docker' 카테고리의 다른 글
[Network | Docker] jar 배포 (0) 2024.07.07 [Network | Docker] Dockerfile (0) 2024.07.05 [Network | Docker] 이미지 (0) 2024.07.04 [Network | Docker] 네트워크 (0) 2024.07.03 [Network | Docker] 데이터베이스 외부 원격 접속 (0) 2024.07.03 다음글이 없습니다.이전글이 없습니다.댓글 - version - Docker Compose 버전을 지정한다. 3.0 버전은 Docker Compose 1.10 및 Docker Engine 1.13.0 이상에서 사용된다.