참고
https://meetup.toast.com/posts/277
Docker Compose와 버전별 특징 : NHN Cloud Meetup
도커는 이제 대부분의 개발자 노트북이나 PC에 하나씩은 설치되어있는 필수품이 되어가는데요 편하고 유용한 도커를 좀 더 유익하고 편하게 사용할 수 있는 도구인 Docker Compose에 대해서 알기 쉽
meetup.toast.com
https://wonhyeok1994.tistory.com/194?category=1057888
도커 볼륨 vs 바인드 마운트
참고 : https://www.dltlabs.com/blog/bind-mounts-volumes-indocker-133067 Bind Mounts & Volumes in Docker We share the fundamentals of Docker and tell you how Bind Mounts and Volumes work. www.dltlab..
wonhyeok1994.tistory.com
도커한테 PEP 사이트 같은곳 성지 ( 사실 여기보고 하면 다됨
https://docs.docker.com/compose/compose-file/compose-file-v3/#image
Compose file version 3 reference
docs.docker.com
이렇게 찾아보면됨
필요한건 읽어서 찾고
Dockerfile과 docker-compose의 주요 차이점은
Dockerfile은 Docker 이미지 를 빌드 하는 방법을 설명하는 반면
docker-compose는 Docker 컨테이너 를 실행 하는 데 사용된다는 것입니다.
Dockerfile의 내용은 Docker 이미지를 만들고 빌드하는 방법을 설명하는 반면
docker-compose는 docker-compose.yaml 파일 에 설명된 설정을 기반으로 Docker 컨테이너를 실행하는 명령입니다
또 하나의 특징은 docker run ~~~ 로 하나씩 컨테이너를 키는게 아니라 'docker-compose'로 다중 컨테이너 실행이 가능한 점이다.
docker-compose 관련 명령어
1.
up
docker-compose.yml 파일의 내용에 따라 이미지를 빌드하고 서비스를 실행합니다.
$ docker-compose -p nhn up -d
Creating network "nhn_default" with the default driver
Creating nhn_mysql_1 ... done
Creating nhn_app_1 ... done
up 명령어로 compose를 실행 시의 단계별 진행사항은 다음과 같습니다.
- 서비스를 띄울 네트워크 설정
- 필요한 볼륨 생성(혹은 이미 존재하는 볼륨과 연결)
- 필요한 이미지 풀(pull)
- 필요한 이미지 빌드(build)
- 서비스 의존성에 따라 서비스 실행
options
- -d: 서비스 백그라운드로 실행. (docker run에서의 -d와 같음)
- --force-recreate: 컨테이너를 지우고 새로 생성.
- --build: 서비스 시작 전 이미지를 새로 생성
- -f: 기본으로 제공하는 docker-compose.yml이 아닌 별도의 파일명을 실행할 때 사용
- docker-compose -f docker-compose.yml -f docker-compose-test.yml up 형태로 두 개의 파일 실행도 가능
- YAML을 두 개 이상 설정할 경우 앞에 있는 설정보다 뒤에 있는 파일이 우선
2.
down
실행 중인 서비스를 삭제합니다.
컨테이너와 네트워크를 삭제하며, 옵션에 따라 볼륨도 같이 삭제할 수 있습니다.
$ docker-compose down
Stopping nhn_mysql_1 ... done
Removing nhn_app_1 ... done
Removing nhn_mysql_1 ... done
Removing network nhn_default
options
- -v, --volume: 볼륨까지 같이 삭제
- DB 데이터 초기화하는데 용이함
- 모든 설정을 초기화하고 새로 시작하는 데 사용
3.
stop, start
서비스를 멈추거나, 멈춰 있는 서비스를 시작합니다.
$ docker-compose stop
Stopping nhn_mysql_1 ... done
$ docker-compose start
Starting app ... done
Starting mysql ... done
4.
ps
현재 환경에서 실행 중인 각 서비스의 상태를 표시합니다.
Name Command State Ports
---------------------------------------------------------------------------
nhn_app_1 docker-entrypoint.sh sh -c ... Exit 1
nhn_mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
5.
exec
실행 중인 컨테이너에서 명령어를 실행합니다.
명령어는 다음과 같은 패턴으로 실행됩니다.
docker-compose exec {정의한 service name} {실행될 명령어}
$ docker-compose exec app ./upload_logs.sh
$ docker-compose exec mysql mysql -uroot -psecret todos
$ docker-compose exec -t gitlab-runner gitlab-runner register
docker-compose exec -t <컨테이너명> <명령어>
6.
logs
output으로 나온 log들을 확인할 때 사용합니다.
docker의 logs와 마찬가지로 --follow(혹은 -f)를 하여 실시간으로 나오는 로그 확인이 가능합니다.
$ docker-compose logs -f
Attaching to docker_app_1, docker_mysql_1
app_1 | yarn install v1.22.5
app_1 | info No lockfile found.
app_1 | [1/4] Resolving packages...
app_1 | [2/4] Fetching packages...
app_1 | [3/4] Linking dependencies...
app_1 | [4/4] Building fresh packages...
app_1 | success Saved lockfile.
app_1 | Done in 0.14s.
app_1 | yarn run v1.22.5
app_1 | error Couldn't find a package.json file in "/app"
app_1 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
7. 이건 짧게 말해서 환경변수 등록해서 user: "$(UID):$(GID)" 이런식으로 쓸 수 있단 얘기
Docker Compose Environment
docker compose의 장점으로는 하나를 정의해놓으면 여러 군데서 동일한 동작을 보장하는 것입니다.
하지만 각 실행 환경에 따라 변경되어야 하는 옵션들이 있는데 이것들 때문에 일일이 파일을 수정하는 건 비효율적입니다.
그래서 각 실행하는 환경마다 환경변수 파일을 정의하여 동일한 compose 파일로 각각의 환경과 동적인 옵션으로 실행이 가능합니다.
. env file
기본적으로 docker-compose up을 한 상태에서 . env 파일을 찾아 파일 내부에 있는 값을 환경 변수로 사용합니다.
$ cat .env # 환경변수 파일
TAG=v1.5
$ cat docker-compose.yml # compose 파일
version: '3'
services:
web:
image: "webapp:${TAG}"$
$ docker-compose config # 실제 적용된 옵션
version: '3'
services:
web:
image: 'webapp:v1.5'
$ export TAG=v2.0
$ docker-compose config
version: '3'
services:
web:
image: 'webapp:v2.0'
여러 파일에서 동일한 환경 변수를 설정할 때 사용할 값을 선택하기 위해 Compose에서 사용하는 우선순위는 다음과 같습니다.
- Compose file
- Shell environment variables
- Environment file
- Dockerfile
- Variable is not defined
여러 개의 복잡합인 상황에 따라서 의도하지 않은 설정이 들어가지 않게 우선순위를 잘 파악해보는 것이 중요합니다.
상황에 따른. env 적용 예제
dev, prod, local 환경에 따라서
.env.dev, .env.prod, .env.local 형식으로 할당을 줄 수 있는데
--env-file 옵션으로 환경변수 파일 지정이 가능합니다.
$ docker-compose --env-file ./config/.env.dev up
CLI Environment
아래의 명령어들은 각각 그 아래의 compose 파일이 일치하게 맵핑됩니다.
$ docker run -e VARIABLE1
web:
environment:
- VARIABLE1
$ docker-compose run -e DEBUG=1 web python console.py
web:
environment:
- DEBUG=1
Docker Cli Environment Variable
Compose CLI에서 실행할 때의 참고 변수 키 값 정의가 가능합니다.
https://docs.docker.com/compose/reference/envvars/
Compose CLI environment variables
docs.docker.com
docker-compose
yaml 파일 주 구성
1.
version:
도커 파일 포멧에 대한 내용임. ( Docker Engine 버전과도 관계가 있다. ), 버전따라 services나 특징들이 조금씩 다름
2.
network:
"docker network ls" 에서 나오는 network와 연결
3.
volumes:
도커는 볼륨과 바인드 마운트 개념이 있는데 여기서 volumes: 에 내용은 도커 볼륨 기능
4.
services:
실행하려는 컨테이너들을 정의.
컨테이너를 실행 시킬때 여러 설정값 config 값, 어떤 이미지를 쓸지, 이름은 뭐할지, 바인드마운트 경로는 어디로 할지 에 대한 내용을 정의 해주는 구간. ( 컴포즈에서 가장 핵심적인 구성이다. )
짧게 yaml 문법 :
key:val 구조이고
# 이 주석
val 를 한칸 내려서 쓸 때는 '-' 를 사용
yaml 코드 구조 예시:
1.
key : val
2.
key :
key : val
3.
key :
key : val
key : val
key:
- val
- val
- val
4.
key :
key : val
entrypoint: >
bash -c '
chmod 777 ./docker_files/* &&
source /app/docker_files/ros_entrypoint.sh &&
source /app/docker_files/run_colcon.sh &&
source /app/docker_files/start_server.sh &&
source /app/docker_files/sleep_to_delay_closing_time.sh
'
간단한 예시 랑 각 옵션별 설명
2. network 관련
예를들어 "docker network create --gateway 172.29.0.1 --subnet 172.29.0.0/21 --driver bridge custom_network_bridge"
라고 커스텀 네트워크를 만들었으면
networks:
custom_network_bridge:
driver: custom_network_bridge
external: true
external 설명 -> default 값은 false 이다. true 로 지정시, network를 따로 생성하지 않고 외부에 생성되있는 network 를 검색해서 사용한다. ( 따라서 외부에 없는 네트워크를 쓰려고 하면 에러남 )
------------------------
networks:
custom_network_bridge:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.99.0.0/21
gateway: 172.99.0.1
이렇게 커스텀 네트워크를 docker-compose로 구성후,
networks:
custom_network_bridge:
driver: custom_network_bridge
external: true
이렇게 pre_existing_network 기존에 미리 생성한 네트워크에 물릴 수 있다.
3. volumes: 관련
"docker volume create backup-storage" 이 명령어로 볼륨 생성을 한 후 docker-compose에서 지정해서 쓸 수 있다.
밑에 처럼 쓰면 됨.
volumes:
server_backup_volume:
name: backup-storage
driver: local
4. services: 관련
container_name_2:
image: 사용할 이미지
container_name: 컨테이너 이름(컨테이너간 통신에서 쓰인다,)
hostname: 도커 컨테이너 CLI 창에서 'hostname' 치면 이거나옴
extra_hosts: "/etc/hosts" 에 "192.168.65.2 host.docker.internal"를 추가해준다. docker_host 의 localhost를 IP를 추적한다.
environment: 환경변수 저장
ports: 호스트 OS와 컨테이너의 포트를 바인딩 시킴. ex) HOST:CONTAINER "8080:8080"
expose: ports와 개념은 같지만 호스트 내부의 다른 컨테이너들만 액세스 가능하게 하는 방법 ex) "8080"
sysctls: 커널관련 파라미터 세팅
command: dockerfile 에서 RUN 개념
entrypoint: dockerfile 에서 ENTRYPOINT 개념
network_mode: 'host' 이렇게 직접 docker network를 사용
volumes: "docker volume create backup-storage" 이거로 생성한 볼륨이나 'Mount host paths'를 볼륨으로 지정 가능
restart: 컨테이너 종료시 재시작 자동으로 할지
working_dir: 컨테이너 접속시 시작 디렉터리
depends_on: 컨테이너 이름을 지정해서 의존성을 엮을 수 있다. 컨테이너 생성 순서 관여됨
build:
context: Dockerfile이 포함된 디렉토리의 경로 또는 git 리포지토리 URL
dockerfile: context에 있는 도커파일 이름을 지정
args:
buildno: 빌드 넘버
networks: "network:" 에서 설정한 network들을 별칭으로 사용
custom_network_bridge: <- 이렇게 별칭으로 사용
ipv4_address: 172.29.0.22 <- 해당 네트워크에 고정 IP 주소로 할당
custom_network_bridge:
user:
app-tier:
aliases:
logging:
driver: "json-file"
options:
max-file: "1"
max-size: "100m"
도커 명령어 실행 VS docker-compose 실행
비교
도커 명령어 :
$ docker run -dp 3000:3000 \
-w /app -v ${PWD}:/app \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:12-alpine \
sh -c "yarn install && yarn run dev"
이걸 docker-compose로 변환하면
version: "3.8"
services:
app:
image: node:12-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
이렇게 됨.
도커 명령어 :
$ docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
이걸 docker-compose로 변환하면
version: "3.8"
services:
mysql:
image: mysql:5.7
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:
이렇게 됨.
다른 docker-compose 예시
test_container:
image: ${CONT_DOCKER_IMAGE}
container_name: test_container
hostname: test_container
working_dir: $DOCKER_CONT_PATH/
user: "${USER_ID}:${GROUP_ID}" # 도커 내부에서 root 가 아닌 특정 유저로 접속
environment:
- LANG=C.UTF-8
- LC_ALL=C.UTF-8
- USER_NAME=$USER_NAME
- HOME=$DOCKER_HOME # docker_host의 HOME 과 동일시
# - DISPLAY=$DISPLAY # X11 관련 설정 ( OS가 우분투 일 경우 )
- DISPLAY=host.docker.internal:0.0 # X11 관련 설정 ( OS가 Windows + docker-descktop 일 경우 )
- LIBGL_ALWAYS_INDIRECT=0 # X11 관련 설정 ( OS가 Windows + docker-descktop 일 경우 )
- ROS_MASTER_URI=http://${NETWORK_ABC_CLASS}.${ROSCORE_IP}:${ROSCORE_PORT} # ROSCORE 주소 설정 MASTER URI
- ROS_IP=${NETWORK_ABC_CLASS}.${CONT_IP} # ROSCORE 주소 설정 본인 IP
networks:
test_templete_network:
ipv4_address: "${NETWORK_ABC_CLASS}.${CONT_IP}"
ports:
- '200${CONT_IP}:22' # 외부 포트는 2002 실제 내부로 접속되는건 22 // 포트포워딩
- '10005:10005'
volumes:
- /etc/passwd:/etc/passwd # docker_host의 유저 PW정보를 동기화
- /etc/group:/etc/group # docker_host의 유저 그룹정보를 동기화
- /etc/sudoers.d:/etc/sudoers.d # docker_host에도 되어 있어야 하는 부분 : 도커 컨테이너 내에서 sudo시 비밀번호 입력하지 않고 가능하게끔
- /etc/shadow:/etc/shadow # docker_host의 유저관련해서 암호화된 폴더를 동기화
- /tmp/.X11-unix:/tmp/.X11-unix # X11 관련 설정 ( OS가 우분투 일 경우 )
- /etc/localtime:/etc/localtime
- $HOST_DOCKER_FILES_VOLUME_PATH:$DOCKER_DOCKER_FILES_VOLUME_PATH # 공용 : 도커파일즈
- $HOST_SHARE_VOLUME_PATH:$DOCKER_SHARE_VOLUME_PATH # 공용 : 쉐어 디렉토리
- $HOST_CONT_PATH:$DOCKER_CONT_PATH # 실제 작업공간
restart: ${RESTART}
extra_hosts:
- host.docker.internal:host-gateway # docker_host의 local_host IP를 "/etc/hosts"에 추가해준다. 따라서 local_host는 컨테이너의 localhost이고 host.docker.internal는 docker_host의 localhost이다.
entrypoint: >
bash -c '
sudo touch $HOME/.bashrc &&
sudo chown -R $USER_NAME:$USER_NAME $HOME &&
sudo chown -R $USER_NAME:$USER_NAME $HOME/.bashrc &&
source $CONT_ENTRYPOINT_PATH &&
sleep 3
'
도커 컨테이너간 통신
ㅇ
방법은 2개
1. 포트 포워딩
2. 같은 네트워크 대역으로 편입시켜서 직접 바라보게끔
1. 포트 포워딩
docker-compose.yml을 사용하여 다중 컨테이너 애플리케이션 정의
docker-compose.yml을 사용하여 다중 컨테이너 애플리케이션에 대한 마이크로 서비스 컴퍼지션을 지정하는 방법입니다.
learn.microsoft.com
2. custom network 를 만들어서 "docker network inspect 커스텀네트워크이름" 안의 "Containers" 에 포함되게끔 IP 대역대를 편입시킨 후, 직접 IP를 바라보고 동작시키면 된다.
services 에서
entrypoint
run
command
사용할 때 팁
1. 따로따로 linux 명령어 치는 것보다 " aa && bb && cc " 이런 식으로 구동할 것.
2. 쉘 명령어 쓸때 $@, $? 등 쓰려면 $ -> $$ 이런식으로 2번 써야 인식함.
3. > bask -c ' ~~~ ' 구성을 이용하면 리눅스랑 동일한 구조로써 사용 가능.
예제 1:
entrypoint: >
bash -c '
chmod 777 /app/docker_files/* &&
source /app/docker_files/ros_entrypoint.sh &&
source /app/docker_files/run_colcon.sh &&
source /app/docker_files/start_server.sh &&
source /app/docker_files/sleep_to_delay_closing_time.sh
'
예제 2:
entrypoint: >
/bin/bash -c '
for (( ; ; ))
do
sleep 1
$$CMD 명령어_1
if [ $$? -eq 0 ]; # <- 명령어_1 이 성공 했으면
then
echo "SUCCESS "
$$CMD 명령어_2
sleep 1
break
else # <- 명령어_1 이 실패 했으면
echo "FAILE "
sleep 1
break
fi
echo 'asdasd'
done
'
global variable
yaml 파일 에서는
이런식으로 variables: ~~ 하고
$(키값) 이런식으로 쓰면된다.
하지만 docker-compose에서는 저렇게 못쓴다.
docker-compose 에서 쓰는 방법은 ".env" 라는 파일을 만들어 global variable(TAG) 를 지정하고
docker-compsoe 에서 ${키값} 으로 가져오면 된다.
예시 :
1. env ( docker-compose 있는 디렉토리에 저장 ) 예시 :
2. docker-compose 활용 예시 : 이런식으로도 활용이 가능함.
'협업툴,가상환경 정리 > docker_정리' 카테고리의 다른 글
docker container to container ssh 접속 (1) | 2022.10.05 |
---|---|
docker-compose 예제 정리 (0) | 2022.09.30 |
도커 볼륨 vs 바인드 마운트 (0) | 2022.09.21 |
7_docker 명령어 정리 (전체적으로) (0) | 2022.07.08 |
5_docker 기본 명령어 정리 (이미지 삭제,종료,빌드, 런, 접속까지 + docker network 생성 + 로그확인) (0) | 2022.06.02 |
댓글