docker compose?

  • 다중 컨테이너 애플리케이션을 정의하고 실행하는 도구
  • 전체 애플리케이션 스택의 제어를 간소화하여 서비스, 네트워크 및 볼륨을 이해하기 쉬운 단일 YAML 구성 파일로 쉽게 관리
  • 단일 명령으로 구성 파일에서 모든 서비스를 생성하고 시작

 

docker compose 파일 

  • 사용하는 컴포즈 파일 : 현재 작업 디렉터리에 있는 다음의 파일 사용 
    • compose.yaml (권장) / compose.yml 
    • docker-compose.yaml / docker-compose.yml

 

 

compose.yaml 파일 구성  

  • services: 여러 서비스를 정의 (이름을 string으로)
    •  서비스 이름과 각 서비스 컨테이너에 적용되는 구성이 포함
  • build: 소스에서 컨테이너 이미지를 생성하기 위한 빌드 구성을 지정
  • ports: 호스트 머신과 컨테이너 간의 포트 매핑을 정의
  • image: 컨테이너를 시작할 이미지를 지정
  • environment: 컨테이너에 설정된 환경 변수를 정의
  • volumes: 서비스 컨테이너가 액세스할 수 있는 마운트 호스트 경로 또는 명명된 볼륨을 정의
  • network: 서비스 컨테이너가 연결되는 네트워크를 정의
  • depends_on: 서비스 시작 및 종료 순서를 제어
  • driver_opts: 드라이버에 전달할 키-값 쌍 형태의 옵션 목록을 지정
  • command: 컨테이너 이미지에서 선언된 기본 명령을 재정의
  • restart: 컨테이너 종료 시 플랫폼이 적용하는 정책을 정의
    • restart options :
      • "no": (기본값) 재시작하지 않음
      • always: 컨테이너가 제거될 때까지 항상 컨테이너를 다시 시작
      • on-failure[:max-retries]: 종료 코드가 오류를 나타내는 경우 컨테이너를 다시 시작. [선택적으로 Docker 데몬의 재시작 재시도 횟수를 제한]
      • unless-stopped: 종료 코드와 관계없이 컨테이너를 다시 시작, 서비스가 중지되거나 제거되면 다시 시작을 중지
  • configs: Docker 이미지를 다시 빌드할 필요 없이 서비스가 동작을 조정할 수 있도록 함
  • secrets: 민감한 데이터에 대한 접근 권한을 서비스별로 부여

 

예시 

# compose.yaml

services:
  frontend:
    image: example/webapp
    ports:
      - "443:8043"
    networks:
      - front-tier
      - back-tier
    configs:
      - httpd-config
    secrets:
      - server-certificate

  backend:
    image: example/database
    volumes:
      - db-data:/etc/data
    networks:
      - back-tier

volumes:
  db-data:
    driver: flocker
    driver_opts:
      size: "10GiB"

configs:
  httpd-config:
    external: true

secrets:
  server-certificate:
    external: true

networks:
  # The presence of these objects is sufficient to define them
  front-tier: {}
  back-tier: {}
    • services: 컨테이너로 실행될 서비스 정의
      • frontend 
        • image: example/webapp 이미지를 기반으로 컨테이너 실행
        • ports: 호스트의 443 포트를 컨테이너의 8043 포트에 매핑 (HTTPS 사용 목적)
        • networks: front-tier, back-tier 네트워크에 연결
        • configs: 외부에서 정의된 httpd-config 설정을 주입
        • secrets: server-certificate라는 외부 비밀 데이터를 주입 (보통 SSL 인증서)
        • => frontend 서비스는 웹 서버 역할을 하며 HTTPS 통신을 위한 인증서와 설정 파일이 필요하고, backend와도 통신해야 하므로 두 네트워크에 모두 연결됨 
      • backend
        • image: example/database 이미지를 기반으로 실행
        • volumes: db-data 볼륨을 /etc/data에 마운트
        • networks: back-tier 네트워크에만 연결
        • => backend는 데이터 저장 역할을 하며, db-data 볼륨을 통해 데이터를 유지. frontend와만 통신 가능하도록 back-tier만 연결.
    • volumes: 서비스에 마운트할 외부 스토리지 설정
      • db-data: 이름이 지정된 볼륨
      • driver: flocker: Flocker라는 스토리지 드라이버 사용 (컨테이너 간 데이터 공유 및 영속성을 보장)
      • driver_opts: 크기를 10GiB로 제한
      • => backend가 사용하는 DB 데이터를 외부 스토리지에 영속적으로 저장
  • configs: 서비스에 주입할 외부 설정 파일
    • 외부에 존재하는 설정 파일 (httpd-config)을 Compose 파일에서 참조만 함
    • frontend 서비스에서 사용
    • => 컨테이너에서 필요한 웹 서버 설정 파일을 미리 준비해두고 재사용
  • secrets: 보안 상 민감한 정보 (예: 인증서, 비밀번호 등)
    • 외부에 이미 존재하는 server-certificate 비밀 정보를 Compose에서 참조
    • =>  HTTPS 구성을 위한 SSL 인증서 또는 개인키 등을 안전하게 전달
         
  • networks: 서비스 간 통신을 위한 네트워크 정의
    • 빈 객체로 정의만 하면 Docker가 기본 설정으로 네트워크 생성
    • front-tier: 외부 통신 또는 사용자와 연결되는 네트워크
    • back-tier: frontendbackend 간 내부 통신 전용 네트워크
    • => 네트워크 분리 이유: 보안성과 효율성을 위해 외부와 내부 네트워크를 구분

 

 

docker compose 명령어 

$ docker compose [OPTIONS] COMMAND

 

Options: 

  • -f, --file stringArray                  Compose configuration files
  • -p, --project-name string        Project name

 

Commands :

      • build       Build or rebuild services
      • up           Create and start containers
      • down      Stop and remove containers, networks
      • logs        View output from containers
      • ps           List containers
      • restart    Restart containers

 

 


* docker compose 
https://docs.docker.com/compose/

* Compose file reference
https://docs.docker.com/reference/compose-file/

 

'! > docker' 카테고리의 다른 글

docker network  (0) 2025.04.15
docker volume, bind mounts  (0) 2025.04.12
Dockerfile  (0) 2025.04.04
Docker CLI 명령어  (0) 2024.11.14
Docker 설치 (MacOS)  (0) 2022.09.05

docker network? 

  • 컨테이너가 서로 연결하고 통신하거나 Docker가 아닌 워크로드와 통신할 수 있는 기능
  • Docker의 네트워킹 하위 시스템은 드라이버를 사용하여 플러그형으로 연결

 

docker network driver 종류와 사용 예제 

 

bridge

  • 기본 네트워크 드라이버
  • 동일한 브리지 네트워크에 연결된 컨테이너들이 통신할 수 있도록 하는 동시에 해당 브리지 네트워크에 연결되지 않은 컨테이너들과 격리

 

bridge 네트워크 설정 및 사용 예제

 

$ docker network create my-bridge
  • my-bridge 이름의 브릿지 네트워크 생성 

 

$ docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
de9c8e373986   bridge      bridge    local
  • 도커 네트워크 목록 확인 

 

$ docker network inspect my-bridge
[
    {
        "Name": "my-bridge",
        "Id": "8e1b132eb066fb9b143edad8e72fc04e4ffd335227005e2ccc885ce31811b40a",
        "Created": "2025-04-15T05:48:15.075292759Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "49c0db95eb0d8069e5b2dfcfb431a4670bc763b347b07fe8cf7ab092338b4b38": {
                "Name": "container2",
                "EndpointID": "fed67438d8ca789eda63b5c394323e33f942147cc48bf934180ba8f2c6ff5939",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "d499eb01fec62647d3fe3b87565bdb60bc7bc40fdcaa986aee3c7a9427659ef9": {
                "Name": "container1",
                "EndpointID": "0f664af14246c6729df37200ca7bf1046ba61396434ee8801cad47f4ed33c77f",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
  • 네트워크 상세 정보

 

$ docker run -dit --name container1 --network my-bridge nginx
$ docker run -dit --name container2 --network my-bridge alpine
  • 네트워크를 지정해서 컨테이너 생성
  • docker run option) --network network : Connect a container to a network

 

$ docker exec -it container2 ping container1
PING container1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.332 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.339 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.419 ms
...
  • container2에서 container1에 ping 명령어로 통신이 가능한지 확인 

 

 

host

      • 컨테이너는 호스트의 네트워킹 네임스페이스를 공유
      • 호스트의 포트 사용, 컨테이너에 자체 IP 주소가 없음 (포트 매핑 -P 필요없음)
      • 같은 포트를 여러 컨테이너에서 사용할 수 없음
      • Linux 컨테이너만 지원

 

host 네트워크 설정 및 사용 예제

$ docker run -d --name nginx-host --network host nginx
  • niginx-host 이름으로 nginx 컨테이너를 호스트 네트워크 모드로 실행
  • nginx는 호스트의 80번 포트를 사용하므로 80번 포트 사용 
  • 호스트 머신의 IP/포트를 그대로 사용하기 때문에 포트 바인딩(-p) 없이도 바로 접근 가능 (브라우저에서 http://localhost 접속)

 

※ 주의

host 네트워크는 docker network create 로 생성 불가 

docker run 에서 --network host 로 설정 !! 

 

 

 

overlay

  • 여러 Docker 데몬 호스트 간에 분산 네트워크를 생성
  • Swarm 서비스 간 연결을 생성하는 데 자주 사용

 

 

docker network 명령어 

 

$ docker network COMMAND

 

Commands :

  • connect        Connect a container to a network
  • create           Create a network
  • disconnect   Disconnect a container from a network
  • inspect         Display detailed information on one or more networks
  • ls                   List networks
  • prune            Remove all unused networks
  • rm                 Remove one or more networks

 

 


* docker/networking
https://docs.docker.com/engine/network/

* docker network
https://docs.docker.com/reference/cli/docker/network/ 

'! > docker' 카테고리의 다른 글

docker compose  (0) 2025.05.29
docker volume, bind mounts  (0) 2025.04.12
Dockerfile  (0) 2025.04.04
Docker CLI 명령어  (0) 2024.11.14
Docker 설치 (MacOS)  (0) 2022.09.05

docker volume? 

  • Docker가 생성하고 관리하는 컨테이너의 영구 데이터 저장소
  • 명령을 사용하여 볼륨을 명시적으로 생성할 수도 있고, Docker가 컨테이너 또는 서비스 생성 중에 볼륨 생성 가능 
  • 볼륨을 생성하면 Docker 호스트의 디렉터리에 저장. 볼륨을 컨테이너에 마운트하면 이 디렉터리가 컨테이너에 마운트
  • 볼륨이 Docker에 의해 관리되고 호스트 머신의 핵심 기능과 분리

 

volume

  • 도커 볼륨 관리 
$ docker volume COMMAND

 

Commands:

  •   create       Create a volume
  •   inspect     Display detailed information on one or more volumes
  •   ls               List volumes
  •   prune        Remove all unused local volumes
  •   rm             Remove one or more volumes

 

docker volume 사용  

  • docker run 명령어에서 --mount 또는 --volume 옵션으로 도커 볼륨에 마운트 
  • 아직 존재하지 않는 볼륨으로 컨테이너를 시작하면 Docker가 볼륨을 자동으로 생성

 

--mount 

  • docker run option)--mount mount : Attach a filesystem mount to the container
$ docker run --mount type=volume[,src=<volume-name>],dst=<mount-path>[,<key>=<value>...]
  • src : 마운트의 소스. 명명된 볼륨의 경우 볼륨의 이름 / 익명 볼륨의 경우 이 필드는 생략
  • dst : 컨테이너에 파일이나 디렉토리가 마운트되는 경로

 

--volume, -v

  • docker run option) -v, --volume list : Bind mount a volume
$ docker run -v [<volume-name>:]<mount-path>[:opts]
  • 콜론(:) 으로 순서 구분 

 


bind mounts?

  • 호스트 머신의 파일이나 디렉터리가 호스트에서 컨테이너로 마운트
  • 컨테이너에서 파일을 생성하고 해당 파일을 호스트의 파일 시스템에 보관

 

bind ounts 사용 

  • docker run 명령어에서 --mount 또는 --volume 옵션으 바인드 마운트

 

--mount 

  • docker run option)--mount mount : Attach a filesystem mount to the container
$ docker run --mount type=bind,src=<host-path>,dst=<container-path>[,<key>=<value>...]
  • src : 호스트에서 파일 또는 디렉터리의 위치 (절대 경로 또는 상대 경로)
  • dst : 컨테이너에 파일이나 디렉터리가 마운트되는 경로 (절대 경로)
  • 지정된 마운트 경로가 호스트에 없으면, 디렉토리를 자동으로 생성하지 않고 오류 발생 

 

--volume , -v

  • docker run option) -v, --volume list : Bind mount a volume
$ docker run -v <host-path>:<container-path>[:opts]
  • 콜론(:) 으로 순서 구분
  • Docker 호스트에 아직 존재하지 않는 파일이나 디렉터리를 바인드 마운트 하는 경우, Docker가 자동으로 호스트에 디렉터리를 생성 (항상 디렉터리로 생성)

 

 


* docker Volumes 
https://docs.docker.com/engine/storage/volumes/

* Bind mounts
https://docs.docker.com/engine/storage/bind-mounts/

'! > docker' 카테고리의 다른 글

docker compose  (0) 2025.05.29
docker network  (0) 2025.04.15
Dockerfile  (0) 2025.04.04
Docker CLI 명령어  (0) 2024.11.14
Docker 설치 (MacOS)  (0) 2022.09.05

Dockerfile?

  • 도커 이미지를 빌드하기 위한 명령어가 들어 있는 텍스트 파일
  • Docker는 Dockerfile에서 명령어를 읽어 이미지를 빌드
  • default 파일 이름 : (파일 확장자 없이) Dockerfile
  • 도커파일 빌드 명령어 :  $ docker build 

 

Dockerfile 지시어 

instruction description
FROM <image> 베이스 이미지 정의

* 도커파일은 FROM으로 시작
RUN <command> 명령어를 실행하여 현재 이미지 위의 새로운 레이어 생성
WORKDIR <directory> 다음의 모든 RUN, CMD, ENTRYPOINT, COPY, ADD 명령어에 대한 작업 디렉터리를 설정
COPY <src> <dest> <src>경로에 있는 새로운 파일이나 디렉토리를 컨테이너 파일 시스템의 <dest>경로에 복사하고 추가

* 빌드 컨텍스트 또는 멀티스테이지 빌드 안에서 한스테이지에서 컨테이너로 파일을 복사할 때 사용
(build context: docker build 명령어를 실행할 때의 현재 디렉토리)
ADD <src> <dest> <src>경로에 있는  새로운 파일이나 디렉토리를 컨테이너 파일 시스템경로에 복사하고 추가

* COPY와 유사
* 원격 HTTPS와 Git URL에서 파일을 가져오거나, 빌드 컨텍스트에서 파일을 추가할 때 tar파일을 자동으로 추출하는 기능 지원
CMD <command> 컨테이너가 실행될 때 실행할 명령어 설정,
ENTRYPOINT와 함께 쓰일 때는 ENTRYPOINT의 인자를 지정

* 도커파일에서 하나만 존재 (여러개면 가장 마지막 CMD만 실행됨)
* 명령어를 &&로 묶어 여러 명령어 실행 가능
ENTRYPOINT ["excutable", "param1", "param2"] 컨테이너가 실행될 때 기본적으로 실행되는 프로그램을 지정
CMD와 함께 쓰일 때, ENTRYPOINT는 컨테이너의 주 실행 파일을 고정하고 CMD는 기본 인자를 설정
LABEL <key>=<value> 이미지에 다양한 key-value 쌍으로 메타데이터 추가
ENV <key>=<value> 환경변수 key값에 value값 설정

* 컨테이너 실행 시(docker run) -e <varname>=<value> 옵션으로 변경 가능
ARG <name>[=<default value>] 빌드 시 빌더에게 전달해 사용할 변수 정의

*
 Docker 빌드 과정에서만 사용되며, 컨테이너 실행 후에는 사용할 수 없음 (ENV와 함께 사용하면 실행 시점에도 값 유지 가능)
* 컨테이너 빌드 시(docker build) --build-arg <varname>=<value> 옵션으로 값 전달, 변경 가능
EXPOSE <port> 컨테이너 내부에서 사용할 네트워크 포트 지정

* TCP, UDP 선택가능 (default: TCP)
* 실제 포트를 개방하려면 컨테이너 실행시(docker run) -p(수동포트매핑) / -P(자동포트매핑) 옵션으로 포트 개방 해야함 

 

 

Dockerfile 예시

  • Node.js 기반 웹 애플리케이션 Dockerfile (from gpt) 작성 
# 1. 베이스 이미지 설정
FROM node:18-alpine

# 2. 빌드 시 사용할 변수 정의
ARG NODE_ENV=production

# 3. 환경 변수 설정
ENV NODE_ENV=${NODE_ENV}

# 4. 컨테이너 내부 작업 디렉토리 설정
WORKDIR /app

# 5. 프로젝트 파일 복사
COPY package.json package-lock.json ./

# 6. 의존성 설치
RUN npm install --only=production

# 7. 앱 소스 코드 복사
COPY . .

# 8. 포트 설정 (기본적으로 Node.js 앱은 3000번 포트 사용)
EXPOSE 3000

# 9. 실행 명령어 설정
CMD ["node", "server.js"]
            1. node:18-alpine 이미지는 Node.js 18 버전이 설치된 Alpine Linux 기반 경량 이미지
            2. NODE_ENV=production은 기본값으로 설정
            3. ARG NODE_ENV 값을 ENV NODE_ENV로 설정하여 컨테이너 실행 시에도 환경 변수를 유지
            4. 이후 모든 RUN, COPY, CMD 등의 명령어는 /app 디렉토리에서 실행
            5. package.jsonpackage-lock.json을 컨테이너의 /app 디렉토리에 복사
            6. 컨테이너 내부에서 npm install 명령어를 실행
            7. 현재 디렉토리(.)의 모든 파일을 컨테이너의 /app 디렉토리에 복사
            8. 컨테이너가 사용할 포트를 3000번으로 지정
            9. 컨테이너가 실행될 때 node server.js 명령어를 실행하여 웹 서버를 시작

 

 

Dockerfile 실행 방법

1. 작성한 도커파일로 Docker 이미지 빌드 

$ docker build -t myapp .
  • -t : 빌드할 이미지에 태그/이름을 지정
  • . : 현재 디렉토리를 빌드 컨텍스트로 사용

 

 

2. 빌드 완료 후 생성된 이미지 확인

$ docker images

 

 

3. 해당 이미지로 컨테이너 실행 

$ docker run -d -p 8080:3000 myapp
  • -d : 컨테이너를 백그라운드에서 실행됨
  • -p : 컨테이너의 3000 포트를 호스트의 8080 포트로 연결 (http://localhost:8080 으로 접근 가능)

 

4. 컨테이너 상태 확인 

$ docker ps

 

 

 


* dockerfile overview
https://docs.docker.com/build/concepts/dockerfile/#dockerfile-syntax

* dockerfile reference
https://docs.docker.com/reference/dockerfile/

'! > docker' 카테고리의 다른 글

docker compose  (0) 2025.05.29
docker network  (0) 2025.04.15
docker volume, bind mounts  (0) 2025.04.12
Docker CLI 명령어  (0) 2024.11.14
Docker 설치 (MacOS)  (0) 2022.09.05

+ Recent posts