작업 디렉토리 : ex06_docker_compose

 

도커 컴포즈는 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기 위한 도구이다.

YAML파일을 사용하여 서비스를 구성한다.

  • 서비스 시작, 중지 및 다시 구축
  • 실행 중인 서비스 상태 보기
  • 실행 중인 서비스의 로그 출력 스트리밍
  • 서비스에서 일회성 명령 실행

기존 Dockerfile 방식

Dockerfile은 다중 컨테이너를 실행할 때 매우 번거롭다. 각각 컨테이너들 간의 요청 응답을 위해  IP, PORT 설정 다 잡아줘야하고 따로따로 Dockerfile 을 만들어 줘야한다.

 

도커 컴포즈를 사용하면 컨테이너간의 유기적 결합을 손쉽게 해결 할 수 있다.

이번 시간에는 1개의 컨테이너만 도커 컴포즈로 실행해본다.

 

1. docker-compose.yml 파일 생성

version: '3.8'
services:
  mysqldb:
    image: mysql:latest
    restart: always
    volumes:
      - mysql-compose-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_HOST: "%"
      MYSQL_ROOT_PASSWORD: root1234
      MYSQL_DATABASE: rootdb
    ports:
      - "3307:3306"
    networks:
      - docker_default
volumes:
  mysql-compose-volume:

 

2. docker-compose 실행하기

docker-compose up -d

위의 명령어로 실행하면 아래와 같은 오류발생! 이유는 버전이 안맞아서 그런거 같다. (최신 docker-compose는 명령어도 다름)

 

 

최신 문법은 아래와 같다.

 docker compose up -d

 

3. docker-compose로 실행된 컨테이너 확인하기

docker compose ps

 

4. DB 접속기로 접속해보기

문제발생! 접속기로 접속이 안된다. 확인해보니까 docker compose up -d 로 실행할 때 default-network가 자동으로 만들어지던데 그거 때문 인것 같다.

 

 

일단 docker compose down 으로 컨터이너와 network를 지워주자.

 

networks 부분을 추가해주자. (services, networks)

external: true 를 하면 기존에 있는 것을 사용하겠다는 의미. 해당 부분을 추가하지 않으면 계속 새로운 네트워크를 생성해댄다.

version: '3.8'
services:
  mysqldb:
    image: mysql:latest
    restart: always
    volumes:
      - mysql-compose-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_HOST: "%"
      MYSQL_ROOT_PASSWORD: root1234
      MYSQL_DATABASE: rootdb
    ports:
      - "3307:3306"
    networks:
      - docker_default
volumes:
  mysql-compose-volume:
networks:
  docker_default:
    external: true

 

하지만 네트워크를 default로 바꾸어봐도 호스트OS의 DB접속기에서는 여전히 접속이 불가능했다.

 

 

문제해결) 문제원인은 네트워크가 아니라 원격 유저 설정이 되지 않았기 때문이었다.

docker exec -it [CONTAINER ID] bash

컨테이너 OS 접속 후

mysql을 입력 하면 mysql로 접속되는데 접속 후 아래 명령어를 입력하여 원격 유저를 만들어 주면 된다.

mysql> create user 'root'@'%' identified by 'root1234';
Query OK, 0 rows affected (0.04 sec)

mysql> grant all on *.* TO root@'%';
Query OK, 0 rows affected (0.02 sec)

 

꼭 컨테이너에 접속해서 할 필요는 없었다..

docker-compose.yml 에서 environments에 MYSQL_ROOT_HOST를 "%" 로 설정해주면 된다.

이렇게 하면 이제 DB접속기에 문제없이 접속가능할 것이다.

 

아래와 같은 쿼리문을 입력하자.

USE rootdb;

CREATE TABLE person(
	id INT PRIMARY KEY, 
	NAME VARCHAR(100)
);

INSERT INTO person(id, NAME) VALUE(1, 'ssar');
INSERT INTO person(id, NAME) VALUE(2, 'ssar2');

SELECT * FROM person;

 

컨테이너를 종료(docker compose down) 하고 다시 실행(docker compose up -d) 해도 person 테이블의 데이터가 살아있는 것을 확인 하면 이번 실습은 끝!

 

컨테이너 환경변수(environments) 다른걸로 만들 때 볼륨까지 지워야하는거 잊지 말자..

docker volume lsdocker volume rm [VOLUME NAME]

환경변수 : OS에서 사용하는 변수

 

1. 목표

  • MySQL 컨테이너를 설치 (OS는 우분투)
  • MySQL 컨테이너가 설치된 OS에 환경변수를 설정
  • MySQL에서 설정된 환경변수를 사용

2. 작업 디렉토리 위치 (ex05)

/docker/docker_files/lecture/docker_lab/ex05

 

3. 도커파일 생성, 빌드 및 컨테이너 생성

FROM mysql

ENV MYSQL_USER=ssar
ENV MYSQL_PASSWORD=ssar1234
ENV MYSQL_ROOT_PASSWORD=root1234
ENV MYSQL_DATABASE=ssardb

CMD ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]

마지막의 CMD는 캐릭터셋을 UTF-8로 설정하기 위함.

 

도커파일 빌드하기

docker build -t mysql-images ./

 

MYSQL 컨테이너 생성

docker run -d -p 3307:3306 --name mysql-container mysql-images

mysql은 기본 3306포트를 사용하는데 3307로 요청이오면 3306으로 포트포워딩 해주자.

 

4. DB접속기로 검증하기(DBeaver, SQL yog, Mysql Bench 등)

컨테이너가 제대로 실행된 것을 확인했다면 DB 접속기로 잘 접속되는지 확인해보자.

나는 SQL Yog를 사용함~

IP와 Dockerfile에서 설정한 MYSQL_USER, MYSQL_PASSWORD에 입력한 부분을 입력하고 포트로 3307(3306으로 포워딩)을 입력 후 테스트 연결에 성공하면 끝!

 

UTF-8 설정이 제대로 되었는지 SQL yog에서 아래의 SQL문을 실행시켜보자.

 SHOW VARIABLES LIKE 'character_set_%';

value가 utf8mb3 가 나오면 된다.

 

5. 환경변수 확인하기

Dockerfile에서 ENV 로 설정한 OS 환경변수가 제대로 설정되었는지 알아보기 위해 mysql 컨테이너에 접속해보자.

docker exec -it [CONTAINER ID] bash

 

터미널에 정상적으로 접속 되었다면 아래의 명령어를 입력하여 Dockerfile에서 ENV 명령어로 설정한대로 값이 제대로 나오는지 확인하면 된다.

echo $MYSQL_USER
echo $MYSQL_PASSWORD

 

6. Mysql 볼륨

mysql 컨테이너는 자동으로 볼륨을 하나 사용한다. Mysql의 데이터가 해당 볼륨에 저장되는데 문제는 컨테이너가 재실행되면 같은 볼륨을 사용하는 것이 아니라 기존 볼륨을 삭제 후 새로운 볼륨이 생성되어버린다. 그래서 기존 데이터는 모두 지워지게 된다.

 

첫 번째 해결책

이 문제를 해결하기 위해서는 2가지 해결책이있는데 그 중 첫 번째는 HOST에 볼륨을 연결하면 된다.

이는 docker hub의 mysql 공식 사이트에도 있는 내용이다.

 

볼륨연결을 위한 호스트OS에 디렉토리 만들기

디렉토리명: mysql-volume

/docker/docker_files/lecture/docker_lab/ex05/mysql-volume

mkdir mysql-volume

 

 

볼륨 옵션으로 호스트 디렉토리 연결하여 실행

docker run -d -p 3307:3306 -v /home/docker/docker_files/lecture/docker_lab/ex05/mysql-volume:/var/lib/mysql --name mysql-container mysql-images

 

정상적으로 실행 되었다면 mysql-volume 디렉토리에 들어가보면 각종 데이터 파일들이 있는 것을 볼 수 있다.

 

두 번째 해결책

이름이 있는 볼륨 생성하여 실행하기 

위에서 실습했던 내용을 초기화 후 진행 (remove.sh)

 

이 방법은 귀찮게 따로 디렉토리를 만들어도 되지 않아도 되고 그냥 -v 옵션에서 이름만 설정해주면 된다!

docker run -d -p 3307:3306 -v mysql-test-volume:/var/lib/mysql --name mysql-container mysql-images

 

해당 방법으로 실행하면 볼륨을 보는 명령어로 보면 볼륨이 생성된 것을 확인할 수 있다.

docker volume ls

 

이름있는 볼륨 으로 만들었을 때 데이터가 제대로 보관되는지 검증하기

 USE ssardb;
 
 CREATE TABLE person(
	id INT PRIMARY KEY,
	NAME VARCHAR(100)
 );
 
 INSERT INTO person VALUES (1, 'ssar');
 
 SELECT * FROM person;

1. 이름 있는 볼륨으로 만들어진 컨테이너에 sql yog로 접속해서 위의 sql 문을 차례대로 실행한다.

2. 도커 컨테이너 중지 및 삭제(remove.sh)

3. 아래의 명령어로 다시 컨테이너를 생성

docker run -d -p 3307:3306 -v mysql-test-volume:/var/lib/mysql --name mysql-container mysql-images

4. 다시 sql yog로 새로 생성된 컨테이너에 접속하여 SELECT * FROM person; 실행 후 제대로 나오는지 확인!

18강에서 이어서 하는 내용.

 

1. nginx.conf 수정

lb에 설정한 nginx.conf 내용을 수정하자. IP를 찾는것이 비효율적이므로 서버 IP를 직접 설정하는게 아니라 게이트 웨이 주소로 설정하고 포트번호만 server1, server2 것으로 설정하면 좀 더 효율적이 된다.

upstream server1{
                server 172.17.0.1:8081;
}

upstream server2{
                server 172.17.0.1:8082;
}

server{
        listen 80;
        server_name localhost;

        #여기서 server1은 위의 upstream server1을 의미한다.
        location /server1{
                proxy_pass http://server1/;
        }

        #여기서 server2는 위의 upstream server2를 의미한다.
        location /server2{
                proxy_pass http://server2/;
        }

}

/ex04/lb/conf/nginx.conf

 

프록시를 사용한 로드밸런스는 원래라면 더 많은 설정을 만져야하지만 여기까지만 강의해주신다고 하신다.

또한, 이번에는 docker run을 사용해서 3가지 nginx container를 띄웠지만 docker compose를 배우면 한방에 컨테이너들을 유기적으로 결합해서 띄우는 방법을 배울 수 있다고 하심.

 

 

해당 강의는 ex04 디렉토리에서 진행하였음.

 

1. 디렉토리 및 필요한 파일 생성

  • server1
    • webapp
      • index.html
    • Dockerfile
  • server2
    • webapp
      • index.html
    • Dockerfile
  • lb
    • Dockerfile 
    • conf
      • nginx.conf

Dockerfile (server1, server2 동일)

FROM nginx

COPY ./webapp /usr/share/nginx/html

ENTRYPOINT ["nginx", "-g", "daemon off;"]

 

index.html (server1)

<h1>Welcome nginx Server1</h1>

 

index.html (server2)

<h1>Welcome nginx Server2</h1>

 

 

2. Dockerfile 빌드

ex04 디렉토리에서 진행.

docker build -t server1:1.0 ./server1
docker build -t server2:1.0 ./server2

 

3. Docker 이미지 확인 및 실행

docker images

빌드한 이미지가 제대로 생성되었는지 확인 한다.

 

이미지가 제대로 생성되었으면 아래의 명령어로 실행

docker run -d -p 8081:80 --name nginx-server1 server1:1.0
docker run -d -p 8082:80 --name nginx-server2 server2:1.0

docker ps 및 제대로 실행되었는지 확인하는 부분은 생략!

 

4. 구성하려는 서버 구성도

 

5. 설정파일 생성

lb/conf/nginx.conf 파일을 생성한다.

upstream server1{
                server 172.17.0.3:80;
}

upstream server2{
                server 172.17.0.4:80;
}

server{
        listen 80;
        server_name localhost;

        #여기서 server1은 위의 upstream server1을 의미한다.
        location /server1{
                proxy_pass http://server1/;
        }

        #여기서 server2는 위의 upstream server2를 의미한다.
        location /server2{
                proxy_pass http://server2/;
        }

}

여기서 upstream server1, upstream server2 IP는 docker inspect [CONTAINER ID] 로 확인하여 넣어주어야한다.!!

 

lb용 Dockerfile을 작성한다.

FROM nginx
COPY conf/nginx.conf /etc/nginx/conf.d/default.conf
ENTRYPOINT ["nginx", "-g", "daemon off;"]

 

6. lb 빌드하기

docker build -t lb:1.0 ./lb

 

7. lb 실행하기

docker run -d -p 8080:80 --name nginx-lb lb:1.0

 

8. 로드밸런스 확인하기

192.168.0.3:8080/server1

192.168.0.3:8080/server2 

각각 접속해보고 server1, server2의 index.html 이 뜨면 성공!

 

 

16강에서부터 이어진 내용이므로 ex03/webapp, ex03/conf 디렉토리 생성되어있는 것을 가정한다.

1. Dockerfile 작성

 1 FROM nginx
 2
 3 #COPY webapp /usr/share/nginx/html
 4 #COPY conf/nginx.conf /etc/nginx/conf.d/default.conf
 5
 6 ENTRYPOINT ["nginx", "-g", "daemon off;"]

아직 webapp과 conf에 들어갈 내용이 없으니까 일단 주석 처리 해주자.

 

2. Dockerfile build 및 컨테이너 실행

docker build -t nginx-server ./
docker run -d -p 8080:80 --name some-nginx nginx-server

 

3. default.conf 내용 가져오기

우리가 건드려야할 conf파일을 확인 후 base될 내용을 가져오자.

docker exec -it [CONTAINER ID] bash

실행한 컨테이너의 터미널에 접속한다.

cd /etc/nginx/conf.d

컨테이너의 터미널에 접속했으면 nginx의 default config파일이 있는 곳으로 이동한다.

cat default.conf

 

우리는 default.conf를 base로 하여 설정을 건드려야하므로 해당 내용을 복사해서 만들어둔 호스트의 conf 폴더로 가져오자.

server {
    listen       80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

해당 내용을 복사 → 컨테이너 터미널 종료 → HOST의 conf디렉토리에 nginx.conf 파일을 생성한 후 복사한 내용을 붙여넣기한다.

 

이전 15 RUN명령어 강의에서 기본으로 제공되는 html을 바꾸기 위해서 ./index.nginx-debian.html 이렇게 변경하였는데 그때는 config 파일에 다르게 설정되어있어있어서 그렇다고 하심.

 

4. 기본페이지, 에러페이지 변경하기

우리가 참고할 설정들은 기본 location과 error가 발생했을 때 보여줄 location 이다.

해당 설정을 위해서는 설정파일의 7,17 번째 줄을 변경하면 된다.

에러페이지용 index는 17번째 줄을 보면 50x.html 이름으로 설정되어있고, 기본 location은 index.html로 설정되어있으므로 webapp에 index.html과 50x.html을 생성해준다. (둘다 경로는 /usr/share/nginx/html 로 동일한 것을 볼 수 있다.)

<h1>Error Page!!</h1>

50x.html

<h1>Welcome Nginx!!</h1>

index.html

 

5. Dockerfile 수정 및 재빌드

주석 처리해둔 COPY 명령어 부분을 주석해제 한 후 빌드를 다시 해주자.

  1 FROM nginx
  2
  3 COPY webapp /usr/share/nginx/html
  4 COPY conf/nginx.conf /etc/nginx/conf.d/default.conf
  5
  6 ENTRYPOINT ["nginx", "-g", "daemon off;"]

Dockerfile

 

docker build -t nginx-server:2.0 ./

빌드

 

docker run -d -p 8080:80 --name some-nginx nginx-server:2.0

실행

 

버그발생

docker ps -a  확인 결과 컨테이너가 강제 종료되는 현상

docker logs [CONTAINER ID] : 명령어로 로그를 보니 아래와 같은 로그가 출력되어있었다.

conf에 있는 nginx.conf 에 오타가 나와있어서 수정함!

 

다시 빌드해서 다시 실행시켜 보면 설정한 대로 동작하는 것을 볼 수 있다.

아직 50x 에러를 발생시킬 수 없어서 보여줄 수가 없다.

기본 페이지는 설정한 대로 제대로 뜬다.

 

컨테이너에 터미널로 접속해서 확인해봐도 설정한대로 잘 복사되었다.

설정파일도 제대로 복사된것을 알 수 있다.(/etc/nginx/conf.d/default.conf)

1. 실습준비

그동안의 실습 내용들 모두 정리

nginx, httpd 컨테이너, 이미지 모두 지운 다음 lecture/ex03디렉토리를 생성한다.

 

2. 파일 생성

ex03 디렉토리 안에서 아래와 같이 디렉토리와 Dockerfile을 생성해준다.

mkdir conf
mkdir webapp
touch Dockerfile

 

3. nginx컨테이너 실행

docker run --name some-nginx -d -p 8000:80 nginx

 

4. docker inspect

docker inspect [CONTINAER ID]

nginx의 컨테이너 ID를 입력해서 nginx 컨테이너를 분석해보자.

일단 docker ps로 방금 전에 실행시킨 nginx를 보면 COMMAND가 /docker-entroypoint... 인걸 볼 수 있다.

 

좀 더 자세히 보기 위해서 docker inspect를 사용해서 봐보자. 컨테이너 내부에서 해당 shell 파일을 실행시켜 주는 것 같다.

 

어떤 스크립트인지 컨테이너 내부에서 해당 파일을 찾아보자.

docker-entorypoint.sh는 / 에서 바로 찾아볼 수 있었다.

docker exec -it 32b bash

 

네트워크 정보

컨테이너의 네트워크 정보

여기서 볼건 IPAddress와 Gateway인데 IPAddress는 나중에 다른 컨테이너와 통신이 필요할 때 컨테이너 끼리 내부적으로 데이터를 주고받을 때 필요함. (Spring ↔ MySQL 등등) 근데 아이피 보다는 --name으로 다른 컨테이너를 식별하는게 더 편하다고 하심.

Gateway는 HOST와 연결된 통로라고 생각하면된다.

 

주의 

Dockerfile에 쓰는 EXPOSE 80 같은 명령어는

80포트를 여는 명령어가 아니라 80포트가 열려있음! 이라고 알려주는 표시일 뿐이다.

RUN 

Dockerfile에서 리눅스의 명령어를 실행하고 싶을 때 사용한다.

 

실습1. Dockerfile 작성

  1 FROM ubuntu
  2
  3 RUN apt-get update
  4 RUN apt-get install -y nginx
  5
  6 WORKDIR /var/www/html
  7
  8 COPY ./webapp/index.html ./index.nginx-debian.html
  9
 10 ENTRYPOINT ["nginx", "-g", "daemon off;"]

 

RUN 명령어 실습을 위한 Dockerfile 작성

 

FROM ubuntu

다른 실습과 다르게 ubuntu를 base로 해서 처음부터 설치하는 방식으로 실습하는게 특징. (RUN명령어 실습을 위해서 그러신듯)

 

RUN apt-get update

RUN apt-get install -y nginx

컨테이너 실행될 때 리눅스 명령어를 실행하는 것이다.

 

 

WORKDIR

작업 디렉토리를 파라미터로 넘겨받은 경로로 설정한다. 

COPY, BASH 같은 명령어도 모두 해당 경로부터 시작된다.

 

 

COPY

HOST내용물을 CONTAINER로 복사한다.

(호스트)./webapp/index.html →  (컨테이너) /var/www/html/index.nginx-debian.html 로 복사한다.

 

 

ENTRYPOINT : 컨테이너가 실행될 때 무조건 실행되는 명령어

(ENTRYPOINT는 CMD로 대체가능하다고 하심.)

 

ENTRYPOINT에 쓰인 daemon off;는 중요하다! 백그라운드로 실행하지말고 포그라운드로 실행하라는 의미인데 nginx를 백그라운드로 실행하면 컨테이너가 실행하자마자 죽어버린다고 함. (더 이상 실행할 명령어가 없다고 판단하고...) nginx command인 "nginx -g 'daemon off;'" 가 COMMAND로 떠있어야 죽지않음!

 

실습2. 빌드하기 및 확인하기

작성된 Dockerfile을 기반으로 image를 빌드하자.

docker build -t nginx-server:2.0 ./

docker build -t [생성할이미지명][생성할태그] [Dockerfile 위치] 

 

빌드가 다되었다면 이미지가 생성되었는지 확인하자.

docker images

 

실습3. 빌드된 이미지 실행하기

docker run -d -p 8080:80 nginx-server:2.0

결과확인

1. Dockerfile 작성

FROM openjdk:11-jdk-slim
WORKDIR /app 
COPY build/aws-v3-0.0.3.jar ./application.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar"]
#CMD ["--server.port=8080"]

 

WORKDIR 

  • 모든 작업이 해당 디렉토리에서 진행되도록 처음 시작 디렉토리를 지정.
  • 사용자가 터미널로 접근 했을 때도 /app 디렉토리로 바로 접근된다. (docker attach, docer exec -it ~ bash)
  • COPY와 같이 상대경로로 설정되어있다면 처음 시작지점이 WORKDIR에서 지정한 폴더가 된다.
    (  ./application.jar === /app/application.jar)

COPY (vs ADD)

  • build/aws-v3.0.0.3.jar를 복사하는데 파일명은 application.jar로 변경
  • ADD와의 차이점 : ADD는 압축도 풀린다고함. ADD 압축파일.zip ./ #이렇게 하면 압축풀림

ENTRYPOINT

  • 명령어를 실행해주는 것.
  • CMD와 비슷하다.
  • 파라미터로 넘겨받은 것들을 합쳐서 컨테이너 실행 시 실행시켜 준다.
  • Dockerfile을 빌드해서 컨테이너가 실행되면 java -jar -Dspring.profiles.active=dev application.jar 명령어가 자동으로 실행된다. (물론 /app 디렉토리에서)

ENTRYPOINT vs CMD

  • ENTRYPOINT는 컨테이너가 실행될 때 무조건 실행되는 명령어
  • CMD도 컨테이너가 실행될 때 실행되는 명령어 이지만 외부의 값에 따라서 대체가 가능하다. (옵셔널) CMD는 ENTRYPOINT의 파라미터로 넘겨지기도 한다.
CMD ["--server.port=3000"]

이렇게 해놓아도

docker run -d -p 9097:5000 java-server --server.port=5000

컨테이너를 실행할 때 위와 같이 실행시키면 --server.port=5000 으로 실행된다. (Dockerfile에 있는 CMD 대체)

 

정리하자면 무조건 대체제없이 실행되어야할 것들은 ENTRYPOINT로 실행하면될거같고, 내가 run할 때마다 바꿀수도있는 값은 CMD로 설정해두면 될거같다.

 

2. 실습에 필요한 jar 파일 다운로드

https://github.com/codingspecialist/aws-v3/tree/release

 

GitHub - codingspecialist/aws-v3: elastic bean stalk

elastic bean stalk. Contribute to codingspecialist/aws-v3 development by creating an account on GitHub.

github.com

spring project가 jar로 압축되어있는 파일이다.

해당 파일을 build디렉토리에 넣어주자. (Dockerfile에 COPY build/aws-v3.0.0.3.jar 로 해놨으니까.)

2. Dockerfile build

docker build -t java-server:1.0 ./

docker build -t [생성할이미지명][생성할태그] [Dockerfile 위치] 

3. Docker image확인

docker images

빌드 결과가 제대로 생성되었는지 이미지를 확인해주자.

 

4. 컨테이너 실행

docker run -d -p 9097:8081 java-server:1.0

 

현재는 Dockerfile의 CMD 명령어가 없어서 spring.profiles.active=dev가 실행되어 8081이 기본포트로 잡힌다.

(ENTRYPOINT로 -Dspring.profiles.active=dev 를 설정하였기 때문에.)

 

만약에 Dockerfile에 CMD를 추가한다면?

FROM openjdk:11-jdk-slim
WORKDIR /app 
COPY build/aws-v3-0.0.3.jar ./application.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar"]
CMD ["--server.port=8080"]

이렇게 되면 8080 포트가 잡힌다. java -jar -Dspring.profiles.active=dev application.jar --server.port=8080 이라는 명령어가 실행된 것과 같기 때문에.

 

근데 Dockerfile에도 추가하고 run 옵션으로도 추가하면? run옵션으로 추가한 것이 Dockerfile의 CMD 명령어를 대체한다.

docker run -d -p 9097:8800 java-server:1.0 --server.port=8800

이렇게 되면 spring의 내장 tomcat은 8800으로 실행된다.

 

5. 컨테이너 로그 확인

컨테이너 내부의 로그를 보기 위해서는 아래와 같은 명령어로 확인한다.

docker logs [CONTAINER ID]

Dockerfile

도커이미지를 작성할 때 어떤 스크립트를 실행시키는 것을 dockerfile 이라고 한다.

 

Dockerfile 작성하기

vi에디터로 아래와 같이 작성 (파일이름을 Dockerfile로 저장해야한다.)

FROM httpd
COPY ./webapp /usr/local/apache2/htdocs
CMD ["httpd-foreground"]

FROM : 기본이 될 이미지를 지정해준다.

COPY : 복사명령어 (./webapp 디렉토리내용을 /usr/local/apache2/htdocs 에 복사하라는 의미 )

CMD : 실행할 명령어 (httpd를 실행시킨다.) → Dockerfile에서 한번만 작성할 수 있다. (여러 개의 CMD를 입력하면 맨 마지막 CMD만 유효하다.)

 

※ COPY와 -v (volume)의 차이

  • COPY는 Dockerfile에서 사용 / -v는 run 옵션 중 하나이다.
  • COPY는 복사이고 -v는 링크를 거는 것이기 때문에 COPY된 파일을 수정해도 원본은 수정되지 않지만 -v 로 지정된 파일을 컨테이너에서 수정하면 원본인 HOST에 있는 파일이 수정된다.

Dockerfile 빌드하기

docker build -t [생성할이미지명]:[태그명] [dockerfile위치]
docker build -t webserver ./

도커파일을 빌드하는 것은 이전 시간에 한 docker commit과 비슷한데 docker build의 경우 Dockerfile을 가지고 이미지를 만드는 차이가 있다고함.

 

두 번째 파라미터로 경로만 넘겨준다면 "Dockerfile" 이름을 가진 파일을 알아서 찾아서 빌드해준다고 함. 

(만약 Dockerfile이 Dockerfile 이름으로 저장되어 있지 않다면 -f 옵션으로 도커파일명 을 명시해주어야한다.)

docker build -t sample -f Dockerfile-base ./

 

Dockerfile 빌드한 이미지 확인하기

docker images

빌드결과가 이미지로 제대로 반영되었는지 확인한다.

1. Docker hub 저장소 만들기

docker hub 회원이 없다면 회원가입 먼저 진행!

docker hub에 접속하고 나서 repository를 만들어주자.

저장소명 : vim-ubuntu

 

2.Docker Hub Login

실습하는 docker command창에서 도커허브 로그인을 해야 도커허브에 push할 때 엑세스 거부 에러가 뜨지 않는다.

"denied: requested access to the resource is denied"

docker login

위의 명령어를 입력하면 ID/PW를 입력하라고 나오는데 docker hub의 ID/PW를 입력하면 된다.

 

3. 우분투 이미지 실행

우리가 만들 image의 기초가 될 우분투 이미지를 실행해보자.

docker run -dit --name=myUbuntu ubuntu 
docker attach myUbuntu

4. 우분투 컨테이너에 vim 설치하기

아무것도 하지 않은 기본적인 우분투 컨테이너에는 vi 명령어가 존재하지 않는다고 나온다.

심지어 apt-get install도 안된다. (apt update로 레포지토리 정리를 업데이트해줘야함.)

apt update
apt-get install -y vim

 

vi 에디터 설치가 완료되면 /home/ubuntu 디렉토리로 이동해서 아래와 같이 작성하자.

vi hello

wq! 로 저장하고 나오자.

5. 이미지 커밋

docker commit myUbuntu ilikecoding/vim-ubuntu:1.0
docker images

docker images를 해서 커밋한 이미지가 제대로 저장되었는지 확인한다.

6. 이미지 푸시

docker push ilikecoding/vim-ubuntu:1.0

 

6번 까지 진행이 됐다면 docker hub에 접속해서 이미지가 제대로 푸시 되었는지 확인하면 끝!

 

# 컨테이너 삭제
docker stop $(docker ps -a -q --filter name=myUbuntu)
docker rm $(docker ps -a -q --filter name=myUbuntu)

#이미지 삭제
docker images #이미지 확인
docker rmi [우리가 커밋했던 이미지 ID]
docker rmi [기초가된 ubuntu 이미지 ID]

#이미지 다운로드
docker run -dit ilikecoding/vim-ubuntu:1.0 bash

 

이미지 푸시를 위해 생성되었던 컨테이너, 이미지들을 모두 지우고 docker hub에서 다시 다운로드 받아서 확인해보면 우리가 /home/ubuntu에 만들었던 hello 파일이 그대로 있는것을 확인할 수 있다.

 

 

[TIP]

Ubuntu Container에서 Bash가 실행중인 상태인데 exit를 하면 컨테이너가 종료되어버린다. 컨테이너가 종료되지 않으려면 Ctrl + P ▶Ctrp + Q 를 하면 그대로 컨테이너가 유지되면서 터미널을 나올 수 있다.

+ Recent posts