지금 이 블로그도 그렇듯 서버내 모든 서비스가 도커 내에서 돌아가고 있다. 서버 맨 앞에 nginX를 두고 적절한 도커 컨테이너로 연결을 중계해 준다. 이때 기본 nginX로 다루기 껄끄러운 커넥션은 다시 Rust를 통해 다시 핸들링한다.
이런 구조속에서 각 컨테이너간 서로 통신해야할 일이 생길수 있다. 나로 같으면 PHP와 MySQL를 서로 연결해줘야 하는 상황이 생긴것이다. 짜피 Docker-Compose를 쓰기에 PHP와 MySQL을 1:1로 연결하는거면 별 문제 없이 할 수 있었겠으나, 1:N (단일 MySQL 컨테이너에 여러개의 의존 컨테이너가 붙는) 구조를 원하고 있었다. 아래에서 external_network를 이용해 서로간 통신하는 구조를 만든것을 설명한다.
여러개와 통신하는 컨테이너
나로 들자면 MySQL 컨테이너이다. MySQL 컨테이너는 다른 컨테이너에 문제가 생겨도 독립적으로 작동을 이어나간다.
적절한 곳에 mysql 폴더를 만들고 아래와 같이 docker-compose.yml를 작성한다
ersion: "3.8"
services:
db:
image: mariadb:latest
restart: always
environment:
MYSQL_DATABASE: "esukmeans"
MYSQL_USER: "esukmean"
MYSQL_PASSWORD: "유저 패스워드"
MYSQL_ROOT_PASSWORD: "루트 페스워드"
volumes:
- DB데이터위치:/var/lib/mysql
networks:
- backend
- default
phpmyadmin:
image: phpmyadmin/phpmyadmin
links:
- db
ports:
- 127.0.0.1:8081:80
networks:
backend:
name: backend
이 때 DB 데이터가 저장될 위치와 DB의 설정을 본인에 맞게 설정한다. ./dbdata 처럼 본인이 적합하게 설정하면 된다. (빈 폴더를 만들어서 거기로 설정하자) phpmyadmin은 내가 작업하기 편하려고 만들었다. 굳이 필요없다면 지워도 된다. phpmyadmin을 지우면 db의 default 네트워크를 지워도 된다. (default는 같은 docker-compose.yml 내에서 사용되는 네트워크이다. docker-compose.yml 내 컨테이너끼리는 default 라는 네트워크를 통하여 서로 통신한다.)
networks > backend 에 다시 name 옵션이 붙어있는것을 볼 수 있다. name옵션이 안붙으면 mysql_backend 처럼 docker-compose.yml이 있는 폴더명이 prefix로 설정되버린다. 물론 name 옵션을 안쓰고 mysql_backend 처럼 길게길게 쓸 수도 있겠으나, 마찬가지로 편의를 위해 이름을 backend로 지정하였다.
정상적으로 network가 생성되었다면 docker network ls
로 아래같은 결과를 볼 수 있을것이다:
$ sudo docker network ls
NETWORK ID NAME DRIVER SCOPE
f86b16fe4450 backend bridge local
b5b60714a7f5 bridge bridge local
fef695472c16 host host local
1cf52af1a58a mysql_default bridge local
c09ad3a36036 none null local
MySQL에 붙는 각각의 컨테이너
MySQL에 달라 붙는 컨테이너들이다. 예로 들면 PHP, WordPress등이 될 것이다.
version: "3.8"
services:
php-fpm-74:
build:
context: phpfpm-74-build
dockerfile: ./phpfpm-74
networks:
- backend
volumes:
- 적절한 mount
ports:
- 적절한 포트
networks:
backend:
external: true
여기서 중요한것은 networks에 backend를 정의하고 external 옵션을 부여한 것이다. 위의 MySQL에 사용된 docker-compose에서 name을 abcd로 했으면 backend:
대신에 abcd:
를 입력하면 된다. 이후에 필요한 서비스에서 networks 섹션을 만들어서 끌어오면 된다. 이러면 서로 통신이 가능하다.
version: "3"
services:
web:
image: wordpress:php7.4
ports:
- ...
volumes:
- ...
restart: always
external_links:
- db
environment:
WORDPRESS_DB_HOST: db
networks:
- backend
networks:
backend:
external: true
위 처럼 external_links를 사용할 수도 있다. external_links를 사용하면 networks 내에서 (여기서는 backend) 다른 컨테이너를 찾아낸다. external_links로 연결되면 해당 서버에서 주소를 컨테이너 IP대신 서비스 명만 입력하면 알아서 찾아주므로 매우 편리해진다. 192.168.0.1:3306 대신에 db:3306 처럼 간편하게 접속할수 있음은 물론, 모종의 사유로 IP가 바뀌었을때도 유연하게 돌아간다.
어쨋든 중요한 키워드는 networks
, networks
> name
, networks
> external
, external_link
이다. 이를 주제로 찾으면 더 응용한걸 찾을수 있을것 같다.
docker-compose 버전이 낮으면 안될 수 도 있다. docker-compose 자체의 버전과 docker-compose.yml 상단의 버전이 일정 버전 이하면 알 수 없는 속성이라면서 오류를 뱉어낸다. 이걸 몰라서 골머리를 꽤 앓았었는데, 만약 안되면 꼭 버전을 확인해 보자.
답글 남기기