이미지와 함께 보자면, 호스트OS 내부를 'WORLD INSIDE DOCKER'로 보시면 되고 외부 호스트를 'WORLD OUTSIDE DOCKER'로 보시면 됩니다.
출처: https://stackoverflow.com/questions/40801772/what-is-the-difference-between-docker-compose-ports-vs-expose
ports는 호스트OS와 컨테이너의 포트를 바인딩 시켜줍니다. (ports 3306:3306)
ports는 호스트 포트와 컨테이너 포트를 모두 노출시키기 때문에,
호스트 내부의 컨테이너끼리는 컨테이너 포트로 특정 컨테이너에 접근할 수 있고,
호스트 외부에서는 컨테이너 포트와 바인딩된(연결된) 호스트 포트를 통해 특정 컨테이너에 접근할 수 있습니다.
#"host:container"
ports:
- "8080:8080"
#또는 "container" => 이 경우 host는 랜덤한 값으로 정해짐
ports:
- "8080"
이미지와 함께 보자면, 호스트OS 내부를 'WORLD INSIDE DOCKER'로 보시면 되고 외부 호스트를 'WORLD OUTSIDE DOCKER'로 보시면 됩니다.
출처: https://stackoverflow.com/questions/40801772/what-is-the-difference-between-docker-compose-ports-vs-expose
expose는 호스트 포트를 공개하지 않고 컨테이너의 포트만 공개합니다 (expose 3306)
호스트 내부의 컨테이너끼리는 컨테이너 포트로 특정 컨테이너에 접근할 수 있지만,
호스트 외부의 경우, 외부 호스트에서 특정 컨테이너에 접근하려고 할 때, 그 컨테이너 포트와 바인딩된(연결된) 호스트 포트가 없기 때문에 해당 컨테이너에 접근할 수 없습니다.
이러한 특징 때문에 expose는 도커 내부에서 컨테이너 간의 통신만 필요한 경우에 주로 사용됩니다.
expose:
- "8080"
ports 와 expose는 모두 컨테이너 포트를 노출시키는 역할을 한다는 점에서는 동일합니다.
단, expose로 노출시키는 경우, 호스트 내부에서만 접근이 가능합니다.
반면, ports로 노출시키는 경우에는 호스트 외부의 다른 호스트들도 ports 에 설정한 호스트 포트를 통해 접근이 가능합니다.
ex) A 컨테이너의 expose 를 "8080" 으로 설정해줬다면, 같은 호스트 내부의 B 컨테이너가 8080 포트로 A 컨테이너에 접근 가능. 단, 외부 호스트들은 A 컨테이너에 접근 불가.
ex) A 컨테이너의 ports 를 "3307:3006" 으로 설정해줬다면, 컨테이너의 3306 포트가 호스트의 3307 포트로 매핑된 것 ⇒ 외부 호스트가 해당 호스트의 3307 포트를 통해 A 컨테이너에 접근 가능
즉, 외부 호스트들은 컨테이너의 포트만으로는 컨테이너에 접근할 수 없고, 컨테이너 포트와 매핑된 호스트 포트를 통해서만 호스트 내부의 컨테이너에 접근할 수 있습니다.
이때, 호스트 포트와 컨테이너 포트를 매핑시켜 컨테이너 포트를 노출시키는 것이 ports 이고, 이때 공개된 호스트 포트를 통해 외부 호스트들도 컨테이너에 접근할 수 있습니다.
반면, 호스트 포트를 공개하지 않고 컨테이너 포트만 노출시키는 것이 expose 이고, 공개된 호스트 포트가 없기 때문에 외부 호스트들은 컨테이너에 접근할 수 없습니다.
What is the difference between docker-compose ports vs expose
🧐도커 관련해서 가장 좋은 참고 자료는 공식 문서
Compose file version 3 reference
기능이나 옵션에 대해 궁금한 게 있다면 1차적으로 공식 문서 참고,
그 다음은 직접 테스트해보기 추천.