본문 바로가기

메가존 클라우드 2기 교육/실무 특화

Docker - Dockerfile, 도커 허브, GCP에서 사용

도커 파일

Dockerfile이란?

앞서 다루어 본 Docker 이미지 생성 방법은 베이스 이미지를 바탕으로 일일이 컨테이너를 생성하고, 파라미터를 설정하며, 미들웨어 설치를 통해 만들어진 컨테이너를 Docker 이미지로 생성하였다. 반면에 Docker 팡리은 컨테이너를 생성하는 여러 구성 정보를 하나의 파일로 정리하고 일괄 실행하여 docker build 명령을 통해 Docker 이미지를 작성하는 스크립트이다.


Dockerfile을 구성하는 명령어

명령어 목록. 무조건 대문자로 작성해야 한다.
# 이해를 위한 도커 파일 작성 예시
vi Dockerfile	# 'Dockerfile' 이 이름이 디폴트 이름이다.
//
FROM ubuntu:18.04	# 베이스 이미지. 무조건 첫 줄에 나옴.
MAINTAINER johnlee	# 작성자
LABEL "name"="webserver"	# 라벨(정보전달) 이름
ENV aloha=date		# 환경변수 설정
ENV path=/var/www/html
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install apache2 -y
COPY nihao /var/www/html/nihao
COPY hello.html $path
ADD aws.tar /var/www/html
WORKDIR /var/www/html		# 작업 경로: 명령어가 실행될 경로
RUN echo ohayo >> ohayo.html
VOLUME /var/www/html # -v /tmp:/var/www/html
EXPOSE 80		# 외부에 공개할 포트 (이 포트 넘버로 매핑됨)
ENTRYPOINT ["apachectl"] # ["apachectl", "-D", "FOREGROUND"]	# 추후에 변경 불가
CMD ["-D", "FOREGROUND"] # ["apachectl", "-D", "FOREGROUND"]	# 추후에 변경 가능
//

# 도커 파일 실행을 위한 사전 작업
mkdir test-dockerfile && cd $_
mkdir nihao
echo "<h1>nihao</h1>" > nihao/index.html
echo "<h1>hello</h1>" > hello.html

# aws.tar 파일을 생성한 'test-docker-file' 폴더 안으로 업로드
# 상단의 도커파일 예시를 'test-docker-file'에 작성. 단, 주석은 꼭 지워야한다.
vi Dockerfile
//
FROM ubuntu:18.04
MAINTAINER johnlee
LABEL "name"="webserver"
ENV aloha=date
ENV path=/var/www/html
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install apache2 -y
COPY nihao /var/www/html/nihao
COPY hello.html $path
ADD aws.tar /var/www/html
WORKDIR /var/www/html
RUN echo ohayo >> ohayo.html
VOLUME /var/www/html
EXPOSE 80
ENTRYPOINT ["apachectl"] # ["apachectl", "-D", "FOREGROUND"]
CMD ["-D", "FOREGROUND"] # ["apachectl", "-D", "FOREGROUND"]
//

# 도커파일 빌드 ('Dockerfile' 파일의 이름을 규칙대로 했으므로 '.'만 찍어도 된다.
# 아닌 경우에는 '-f testfile .' 이런 식으로 한다.)
docker build -t hello:v1.0 .

# 빌드한 이미지로 컨테이너 생성
docker run -d -P hello:v1.0
도커파일 내의 명령어 실행도 정상적으로 작동됨.
터미널에 접속하면 바로 작업경로로 접속된다.
환경변수도 잘 적용됨.
마운트된 폴더는 지정할 수 없으므로 이런 식으로 찾아야한다.
불륨 정보. 경로는 알 수 있지만, 마운트 여부를 알 수 없다.

# 이번엔 포트 번호를 다르게 도커파일 생성
vi test-docker
//
FROM ubuntu:18.04
MAINTAINER johnlee
LABEL "name"="webserver"
ENV aloha=date
ENV path=/var/www/html
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install apache2 -y
COPY nihao /var/www/html/nihao
COPY hello.html $path
ADD aws.tar /var/www/html
WORKDIR /var/www/html
RUN echo ohayo >> ohayo.html
VOLUME /var/www/html
EXPOSE 8080
ENTRYPOINT ["apachectl"]
CMD ["-D", "FOREGROUND"]
//

# 도커 빌드 ( '.'은 test-docker의 위치)
docker build -t hello:v1.1 -f test-docker .

# 컨테이너 실행
docker run -d -P hello:v1.1
아파치는 80포트를 Listen하므로 8080포트로는 웹서버에 연결이 불가능하다.
# 컨테이너 터미널 접속
docker exec -it 3beb971d1055 bash

# 업데이트
apt update

# vi 설치
apt install -y vim

# 포트 정보 변경
cd /etc/apache2/
vi ports.conf
//
8080포트로 변경
//

# 아파치 재실행(컨테이너가 종료됨)
service apache2 restart

# 컨테이너 재실행
docker restart 3beb971d1055
현재 80포트만 Listen을 하지만, 아파치에 8080포트를 Listen하도록 설정해주면 가능해진다. (하지만, 되도록 바꾸지 않는 것을 추천)
접속 완료. 하지만 딱히 추천하는 방법은 아니다.

이 외에도 'EXPOSE"를 누락하는 경우도 알아본다.

'EXPOSE를 누락한 경우 포트가 생성되지 않는다. 즉, 사용 불가능.

사용

# 도커파일 생성
cd /tmp
tar cvf test.tar images index.html 
vi Dockerfile
// ADD 명렁어는 tar파일을 자동으로 풀 수 있다. 
FROM nginx:latest
ADD test.tar /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
//

# 빌드
docker build -t test_build:v2.0 .

# 컨테이너 실행
docker run -d -P test_build:v2.0

# 도커파일 생성. nginx 덕분에 마지막 줄의 CMD를 지워도 무방하다.
tar cvf test1.tar images index.html 
vi Dockerfile
// ADD 명렁어는 tar파일을 자동으로 풀 수 있다. 
FROM nginx:latest
ADD test1.tar /usr/share/nginx/html
//

# 빌드
docker build -t test_build:v1.0 .

# 컨테이너 실행
docker run -d -P test_build:v1.0

도커 허브

 회원가입

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Deliver your business through Docker Hub Package and publish apps and plugins as containers in Docker Hub for easy download and deployment by millions of Docker users worldwide.

hub.docker.com

자신이 만든 이미지를 보다 편리하게 공유하기 위한 도커 허브 사이트에 접속해서 회원가입을 진행한다. 간단하기 때문에 금방 끝난다.


Repositories

리포지토리에 자신의 이미지를 업로드하여 공유할 수 있다.
# 태그 달기. (docker tag [소스 이밎] [태그])
# 이미지 이름 앞에 '[사용자명]/'를 달아줘야한다. (도커 허브 경로를 지정해주는 것)
# 이미지를 생성할때 처음부터 사용자명을 붙여준다면 생략 가능
docker tag test_build:v1.0 kyounggu/test_build:v1.0

# 도커 허브 로그인 (자격 증명과 비슷)
docker login

# 도커 허브에 업로드
docker push kyounggu/test_build:v1.0

# 도커 허브 로그아웃(필요한 경우에)
docker logout
태그가 달린 이미지가 생긴다.
도커 허브 로그인
'push'를 하면 리포지토리에 업로드된다.
같은 방식으로 'v2.0'을 업로드하면 사진처럼 업데이트가 된다.

# tester(ubuntu)에서 도커 허브의 리포지토리에서 이미지 가져와 사용하기
# --restart always: 도커가 꺼졌다가 다시 켜질때 같이 컨테이너도 켜진다.
docker run -d -P --restart always kyounggu/test_build:v1.0
같은 방식으로 'v2.0'도 생성.

도커파일 - 워드프레스

webserver

# 'wordpress' 폴더 생성 및 이동
mkdir wordpress && cd $_

# 도커파일 생성
vi Dockerfile
//
FROM centos:7
MAINTAINER itssp0405@gmail.com
RUN yum install -y httpd php php-mysql php-gd php-mbstring wget unzip
RUN wget https://ko.wordpress.org/wordpress-4.8.2-ko_KR.zip
WORKDIR /var/www/html
RUN unzip /wordpress-4.8.2-ko_KR.zip
RUN mv wordpress/* .
RUN chown -R apache:apache /var/www
EXPOSE 80
CMD httpd -DFOREGROUND
//

# 도커 빌드
docker build -t kyounggu/my-wp:v1.0 .

# 이미지 업로드
docker push kyounggu/my-wp:v1.0

# 컨테이너 생성
docker run -d -P --name wordpress2 --network test_bridge kyounggu/my-wp:v1.0

 


dbserver

# 기존 dbserver 삭제
docker rm -f dbserver

# dbserver 컨테이너 생성 실행
docker run -d -p 3306:3306 --name dbserver \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
-e MYSQL_ROOT_PASSWORD=password --network test_bridge mariadb


도커 허브를 통해 ubuntu에 워드프레스 전송

# 도커 허브에 업로드
docker push kyounggu/my-wp:v1.0
도커 허브에 업로드

# ubuntu에서 네트워크 생성 (서브넷과 드라이버는 미입력시 알아서 설정됨)
docker network create test_network
드라이버와 서브넷이 자동으로 설정됐다.

# 우분투에서 dbserver 생성
docker run -d -p 3306:3306 --name dbserver \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
-e MYSQL_ROOT_PASSWORD=password --network test_network mariadb
정상적으로db 컨테이너 생성 완료.

# 도커허브의 이미지를 통해 webserver 구축. 이번엔 80포트 사용
# dbserver의 아이피를 DNS처럼 쓰기 위해 같은 네트워크를 사용
docker run -d -p 80:80 --name wordpress --network test_network kyounggu/my-wp:v1.0

도커 - GCP

GCP VM 생성


GCP에 워드프레스 컨테이너 설치

# 브라우저 SSH창을 통해 도커 설치
sudo su - root
curl -fsSL https://get.docker.com/ | sh
yum -y install bash-completion wget unzip mysql
curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
systemctl enable --now docker

## 워드프레스 dbserver
# dbserver 폴더 생성
mkdir dbserver && cd $_

# 네트워크 생성
docker network create gcp-network

# mysql 컨테이너 생성
# 기본 이미지를 사용할 때는 '-itd' 사용 (bin/bash를 실행해줘서 run 명령어로 컨테이너가 살아있기 때문)
docker run -itd -p 3306:3306 --name mysql --network gcp-network ubuntu:18.04

# mysql 컨테이너에 접속
docker exec -it mysql bash

# apt의 소스 리스트를 카카오 서버의 것으로 수정하고 mariadb 다운(속도 때문)
sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
apt-get update
apt-get install -y mariadb-server

# 50-server 설정 파일의 bind-address 주석 처리
sed -i "s/bind-address/#bind-address/g" /etc/mysql/mariadb.conf.d/50-server.cnf

# mysql 세팅
service mysql start
mysql_secure_installation
service mysql restart

# 워드프레스 데이터베이스, 사용자 생성 및 권한 설정
mysql -u root -p
CREATE USER 'wpuser'@'%' IDENTIFIED BY 'wppass';
CREATE DATABASE IF NOT EXISTS wordpress;
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'%';
quit

# 컨테이너 이름 변경
docker rename mysql dbserver

# 도커 허브에서 이미지를 가져와 webserver 컨테이너 생성
docker run -d -p 80:80 --name my-wp --network gcp-network kyounggu/my-wp:v1.0

AWS에서 GCP 인스턴스의 퍼블릭 아이피로 레코드 등록
# commit을 하기 위해선 서버를 멈춰야한다.
docker stop dbserver my-wp

# 워드프레스 웹서버 commit으로 이미지 저장 후, 도커 허브에 업로드
docker commit -a "kyounggu" -m "wordpress" my-wp kyounggu/gcp-wordpress:tiger
docker push kyounggu/gcp-wordpress:tiger

# 워드프레스 dbserver commit으로 이미지 저장
docker commit dbserver mysql-base:v1.0

# 도커파일 생성 (베이스 이미지만 참조)
vi Dockerfile
//
FROM mysql-base:v1.0
ENTRYPOINT ["mysqld"]
//

# 빌드
docker build -t kyounggu/gcp-dbserver:eagle .

# 도커 허브 업로드
docker push kyounggu/gcp-dbserver:eagle

# 웹, db 서버 삭제
docker rm -f dbserver my-wp

# 도커 허브에서 이미지를 가져와 컨테이너 생성 (설치가 된 모습 그대로 생성된다.)
docker run -d -p 3306:3306 --name dbserver --network gcp-network kyounggu/gcp-dbserver:eagle
docker run -d -p 80:80 --name wordpress --network gcp-network kyounggu/gcp-wordpress:tiger

# 테스트를 위한 댓글 작성

# db 정지
docker stop dbserver

# 현재 DB를 이미지로 저장 후, 업로드
docker commit -a "kyounggu" -m "hello world" dbserver kyounggu/gcp-dbserver:falcon
docker push kyounggu/gcp-dbserver:falcon

# db 삭제
docker rm -f dbserver

# 다시 도커 허브에서 db 이미지를 가져와 생성.
docker run -d -p 3306:3306 --name dbserver --network gcp-network kyounggu/gcp-dbserver:falcon
'egale'버전을 내려 받아 생성하면, 별도의 설치 없이 워드프레스가 실행된다. 이 상태에서 댓글을 작성.
댓글을 작성한 버전을 'falcon'으로 업로드
다시 dbserver를 삭제하고 'falcon'버전을 내려 받아 컨테이너를 만들면 댓글이 그대로 남아있다.

 도커 허브 이용

# 워드프레스의 web, db 서버를 이미지로 저장
docker commit -a "kyounggu" -m "dbserver" dbserver kyounggu/gcp-dbserver:tiger
docker commit -a "kyounggu" -m "wordpress" wordpress kyounggu/gcp-wordpress:eagle

# 도커허브 로그인
docker login

# 도커허브에 저장한 이미지 업로드
docker push kyounggu/gcp-dbserver:tiger
docker push kyounggu/gcp-wordpress:eagle

# 도커의 모든 컨테이너 삭제 ['$(docker ps -a)'에 뜨는 프로세스 모두 삭제]
docker rm -f $(docker ps -a -q)

# 도커의 모든 이미지 삭제
docker rmi -f $(docker images -q)

# 도커허브에 저장한 이미지를 이용하여 컨테이너 생성
docker run -d -p 3306:3306 --name dbserver --network gcp-network kyounggu/gcp-dbserver:tiger
docker run -d -p 80:80 --name wordpress --network gcp-network kyounggu/gcp-wordpress:eagle
업로드가 정상적으로 됐다.