ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker (8)docker-compose
    생활코딩 Docker 2022. 2. 3. 19:10

    ===

    강의요약

    - compose를 이용해서 복잡한 컨테이너들의 관계를 명확하게 문서화, 손쉽게 컨테이너들을 응용

    - 어떤 이미지는 컨테이너로 만들 때 설정정보를 명령어로 복잡하게 입력해야된다,

    - 어떤 이미지는 다른 컨테이너가 필요할수도 있다

    -> 실행방법과 연결하는 정보를 .yaml 에 적어두고, 그 파일을 명령어로 실행하는걸로 바꾼다

     

    - docker-compose up 하면 docker-compose.yml을 찾아서 그 파일에 적혀있는대로 동작 = docker run과 같은 것

    - version, services, 컨테이너이름, image, volumes, environment, depends_on, ports, db:3306...

     

    - docker-compose up 할 때 로그인이 돼야 하는데 wsl에서 로그인이 안되는 오류 -> 이것도 cmd에선 안나

    : https://judae.tistory.com/32

     

    일단 저 코드로 docker-compose up 하면 일단 이거 뜨는 상태

    보니까 에러 메시지가

    docker-practice-db-1   | 2022-02-26T04:01:21.112397Z 0 [ERROR] Could not set file permission for ca-key.pem
    docker-practice-db-1   | 2022-02-26T04:01:21.112429Z 0 [ERROR] Aborting

    이러고 

    docker-practice-db-1   | 2022-02-26 04:01:26+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
    docker-practice-db-1   | 2022-02-26 04:01:26+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
    docker-practice-db-1   | 2022-02-26 04:01:26+00:00 [Note] [Entrypoint]: Initializing database files
    docker-practice-db-1   | 2022-02-26T04:01:26.966961Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    docker-practice-db-1   | 2022-02-26T04:01:26.971538Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
    docker-practice-db-1   | 2022-02-26T04:01:26.971609Z 0 [ERROR] Aborting

     

    이게 반복됨, 스택오버플로우 뒤져보니까 wsl 권한 어쩌고 하길래 cmd에서 했더니 그냥 되네.......

     

    ===

    https://youtu.be/EK6iYRCIjYs

    ===

    도커 컨테이너를 실행할 때 아래와 같이 복잡한 명령어를 입력해야 한다면 명령어를 기억하는 것이 쉽지 않을 것입니다.

    docker \

    run \

       --name "db" \

       -v "$(pwd)/db_data:/var/lib/mysql" \

      -e "MYSQL_ROOT_PASSWORD=123456" \

      -e "MYSQL_DATABASE=wordpress" \

      -e "MYSQL_USER=wordpress_user" \

      -e "MYSQL_PASSWORD=123456" \

      --network wordpress_net \

    mysql:5.7

     

    그런데 실행해야 할 컨테이너가 하나가 아니라 수십개라면 컨테이너를 실행하는 것은 여간 까다로운 일이 아니겠죠. 실행방법을 파일에 적어두고 아래와 같이 한줄의 명령어로 실행할 수 있다면 얼마나 좋을까요?

    docker-compose up

    이것을 가능하게 해주는 것이 docker compose 입니다.

     

    ===

    도커 컨테이너를 만드는 명령이 엄청 복잡하다면? 만들때마다 귀찮을 것

     

    도커를 전혀 모르는 동료라면? 저런게 엄청 부담스러울 것

    이런 상황에서,

    docker-compose.yml이라는 파일을 만들고, 저 코드와 똑같은 일을 하는 코드를 작성하고, 

    콘솔에서 docker-compose up이라는 단 한줄의 명령어를 실행하고 엔터치면 컨테이너가 만들어져

     

    ===

    *compose : 구성하다, 작곡하다, 편지/연설문/시를 정성 들여 쓰다

     

    ===

    수업의 시나리오

     

    설치형 블로그 Wordpress

    얘를 도커 이미지를 이용해서 컨테이너를 만들어서 실행하고 싶다

    근데 Wordpress이미지는 MySQL컨테이너가 하나 더 필요해 -> 이미지가 컨테이너가 하나 더 필요한 경우

    그래서 컨테이너 두개를 만들고 연결시키면

     

    Web Browser에서 Wordpress에 접속하면,

    Wordpress 컨테이너가 MySQL에 접속해서 여러가지 작업을 하고 결과를 가져온 다음에 그것을 Web Browser에게 보내주게됨

    이런 시나리오의 환경을 docker compose를 통해서 만들어 볼 것

     

    ===

    https://bit.ly/docker-compose-sample

    실습에서 사용할 명령어와 설정파일

    command

    docker network create wordpress_net
    docker \
    run \
        --name "db" \
        -v "$(pwd)/db_data:/var/lib/mysql" \
        -e "MYSQL_ROOT_PASSWORD=123456" \
        -e "MYSQL_DATABASE=wordpress" \
        -e "MYSQL_USER=wordpress_user" \
        -e "MYSQL_PASSWORD=123456" \
        --network wordpress_net \
    mysql:5.7
    docker \
        run \
        --name app \
        -v "$(pwd)/app_data:/var/www/html" \
        -e "WORDPRESS_DB_HOST=db" \
        -e "WORDPRESS_DB_USER=wordpress_user" \
        -e "WORDPRESS_DB_NAME=wordpress" \
        -e "WORDPRESS_DB_PASSWORD=123456" \
        -e "WORDPRESS_DEBUG=1" \
        -p 8080:80 \
        --network wordpress_net \
    wordpress:latest

    docker-compose.yml

    version: "3.7"
    
    services:
      db:
        image: mysql:5.7
        volumes:
          - ./db_data:/var/lib/mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: 123456
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress_user
          MYSQL_PASSWORD: 123456
      
      app:
        depends_on: 
          - db
        image: wordpress:latest
        volumes:
          - ./app_data:/var/www/html
        ports:
          - "8080:80"
        restart: always
        environment:
          WORDPRESS_DB_HOST: db:3306
          WORDPRESS_DB_NAME: wordpress
          WORDPRESS_DB_USER: wordpress_user
          WORDPRESS_DB_PASSWORD: 123456 

     

    ===

    맨 처음 나오는 것부터 설명 적기

    command vs .yaml 하는 것임

    일단 command로 치는것부터 한줄 한줄 설명 할 것

     

    docker network create workpress_net

     : 네트워크 생성하는 명령어  --뒤에 설명 나옴

     

    그 다음 명령어

    run 명령 : db라는 이름mysql이미지기반 컨테이너 만드는

    호스트에 db_data라는 폴더가 생김(-v옵션이 폴더가 없어도 만듦), 이곳에 mysql의 데이터가 저장된다 : 컨테이너를 껐다 켜도 데이터가 유지

     

    https://hub.docker.com/_/mysql

    가서 보니까 /var/lib/mysql이랑 -v하라고 돼 있어, 저기에 데이터가 생기는 듯

     

    wordpress를 실행하는 컨테이너, run 어쩌고

     

    mysql과 wordpress가 실행됐고, 두개의 컨테이너는 wordpress_net이라는 네트워크에 연결된 상태

    wordpress도 마찬가지로 host에 파일을 copy하고 있다, 저 DB_HOST는 뒤에 나옴(네트워크)

     

    ===

    wordpress에 접속하자,

    8080에 연결되도록 우리가 컨테이너를 만듦 : localhost:8080

    ->설치하는 화면 나옴

     

    ===

    지금까지 명령어로 워드프레스를 실행해봤는데

    이렇게 복잡한 명령을 기억하고 있기 쉽지 않다

    간단하게 compose up 이라고 하면 이렇게 실행되도록 하는 설정파일을 만들 수 있다

     

    기존 컨테이너 지우기

    docker rm --force app

    docker rm --force db

    docker network rm wordpress_net 네트워크도 삭제

    생성됐던 폴더들도 삭제

     

    ===

    docker-compose.yml

    약속된 이름의 파일

    명령어로 실행했던 것과 똑같은 취지의 코드

    docker-compose up

     : docker-compose 한테 up 하면 docker-compose.yml을 찾아서 그 파일에 적혀있는대로 동작함

    잘됨

     

    컨테이너 끌 땐

    docker-compose down

     

    ===

    .yaml에 대한 설명

     

    제일 먼저 할건 MySQL Server를 만들어야한다,

    얘는 /var/lib/mysql라는 폴더에 데이터가 저장,

    3306포트에 리스닝

     

    얘를 만들기 위해선

     

    version:

    docker-compose파일에선 일단 파일의 버전을 적어야 함. : compose file format

    services:

    이 안에 만들고자 하는 컨테이너들이 들어오게 됨, 거기에 image: mysql:5.7을 통해 mysql을 생성해라 라고 시킬 수가 있는 것

     

    이 밑에 바로 오는건 컨테이너의 이름(db, app)

    db:

    app:

    쉘에선 --name옵션

    컴포즈에서는 db라고 하는 지시어가 컨테이너의 이름

     

    ---

    뭐가 뭔지 전체적인 그림

    잘 안보이니 크게1

    잘 안보이니 크게2

     

    ---

    image는 쉘에선 docker run mysql:5.7 에 해당  --이미지를 뭘 쓸거냐

    이때 문제가 있다.

    데이터베이스 컨테이너 안에 파일이 저장되니까, 컨테이너를 새로만들거나 하면 데이터가 유실됨

    /var/lib/mysql 데이터를 호스트에다가 저장한다면 데이터가 안전하게 유지될 수 있다

    호스트에다가 db_data라는 폴더를 만들고, 컨테이너의 /var/lib/mysql 와 연결시키기

    쉘에서는 -v "$(pwd)/db_data:/var/lib/mysql"

    *pwd는 현재 디렉토리

    똑같은 작업을 compose에서는 volumes라는 지시어

    .yaml파일에선 ./로 해도 되네, 명령어에선 해보니까 안되던데

     

    ▽\(백슬래시) 는 어차피 엔터는 의미 없으니까 보기쉬우라고 써놓은 듯?

     

    ===

    한가지 더 해야할 것은 컨테이너가 만들어질 때 MySQL서버의 username, id, pw 등의 필요한 정보들을 세팅해야

    그때 쉘에서는 -e옵션을 써서 컨테이너를 만든 사람이 제시하는 환경 변수들을 세팅하면 됨, 그럼 그 데이터들이 흘러들어가서 컨테이너가 만들어질 때 세팅이 된다

    compose에서는 environment라는 지시어에 의해 할 수 있다

     

    restart는 별말 안함

     

    ===

    이번엔 wordpress앱을 컨테이너로 만들기

    여기엔 아파치 웹서버가 설치돼 있고,

    PHP가 설치돼 있고,

    /var/www/html/에 PHP로 만든 소스코드가 보관됨, 웹서버는 80번 포트에 리스닝  --▽이미지를 이렇게 만들어놨다 이거겠지?

     

    ===

    docker run wordpress:latest 라고 하면 최신버전이 컨테이너로 만들어짐

    compose에선 image: wordpress:latest 라고

    근데 얘는 MySQL서버를 이용하고 있다. 그래서 MySQL서버가 더 먼저 만들어질 필요가 있다

    선행과 후행을 docker-compose에서 명확하게 할 때는 depends_on이라는 지시어를 쓴다

    db컨테이너가 먼저 만들어지고 그 다음에 우리의 wordpress(app)가 만들어짐

    이름붙이는건 위랑 똑같아

    -v도 똑같아

     

    이때 외부에서 접속을 할 수 있어야 하는 컨테이너가 있고 : wordpress컨테이너

    외부에서 보안상의 이유로 접속하지 못하도록 하는게 좋은 컨테이너가 있다 : mysql, 얘는 app컨테이너만 접속할 수 있게 해야 안전해

     

    그래서 app컨테이너의 80번 포트와, 호스트의 8080포트를 연결

    쉘은 -p옵션, compose는 ports지시어  --MySQL은 포트 안했잖아? 지들끼리 연결하는건 여기 environment에 있어

     

    우리가 만든 애플리케이션이 데이터베이스에 접속하기 위해서 데이터베이스의 정보들이 필요

    그 정보는 쉘에선 환경변수로, compose의 똑같은 작업은 environment

    근데 wordpress입장에서 db에 접속할 때, db의 주소는 HOST에다가 지정하는데, 원래 IP같은 이름들을 적음.

    보시면 db라고 돼 있죠? 이렇게 컨테이너의 이름을 적으면 얼마나 편하겠어 이걸 하기 위해선 해줘야 하는게 있다

    네트워크 라는걸 만들어야해

    이렇게

    쉘에선

    docker network create workpress_net 이라고 해주면 네트워크가 형성됨

    db컨테이너를 네트워크에 연결

    --network라는 옵션에 wordpress_net 이라는 이름을 붙이기, workpress도 마찬가지

     

    이때 재밌는점, docker-compose에서는 네트워크를 만들고 연결하는 작업을 할 필요가 없다

    docker-compose를 만드는 순간에 자동으로 네트워크가 만들어지고 컨테이너들은 그 네트워크에 자동으로 연결이 됨

    ▽그럼 이름으로 쓸 수 있다 이거지 depends_on: db이거

     

    ===

    이러고 웹브라우저에서 http://localhost:8080 이라고 치면 어떤 일이 일어나는지

    8080로 들어오면 80번 포트에 연결돼있는 app컨테이너의 웹서버로 접속

    웹서버는 PHP에게 요청을 넘기고 PHP는 /var/www/html/에 위치하고 있는 php애플리케이션을 읽어서 거기에 있는대로 동작(웹서버가 이렇게 동작하는구나..)

    그때 코드에 db에 접속하는 정보를 입력하면 : 저기 대화 상자에 있는 mysql_connect('db', ..... )  --첫번째는 host name, 그 db는 같은 네트워크에 접속돼 있는 db라는 이름의 컨테이너를 의미함 그럼 3306으로 접속됨(▽.yaml에 db:3306이라 써놨으니까)

     

    그럼 3306을 리스닝하고 있는 mysql서버가 그걸 받고, mysql서버는 /var/lib/mysql 이라고 하는 디렉토리에 연결돼있는 db_data라는 폴더에서 데이터를 꺼내서 그 결과를 PHP에 줌

    PHP는 웹서버에게 응답

    웹서버는 웹브라우저에게 결과를 알려주면 

    웹브라우저에는 wordpress가 실행

     

     

Designed by Tistory.