도커 2일 차 실습 정리 🧐
DB에 도커 볼륨 적용하기
1) 도커 데스크탑의 " Volume " 탭에서 볼륨 생성을 클릭한뒤 볼륨 명을 적어준다.
2) 사전에 Pull 해놨던 mysql 이미지를 Run 하는데, 이때 생성한 볼륨을 추가해준다.
➡ 이때 경로는 /var/lib/mysql
로 해준다. 이 경로가 실제 mysql 에서 데이터를
저장해놓는 경로이기 때문이다.
3) 실행된 DB 컨테이너를 MySQL Workbench로 접속한 뒤 test
이름의
데이터베이스를 생성해본다.
4) 그런 다음, 실행중인 컨테이너를 삭제한뒤, 다시 동일한 방식으로 새로운 컨테이너를
실행시켜본다.
이때, 볼륨 설정을 따로 해주지 않았다면, DB에 접속해도 아무것도 생성된 것이 없을
것이다. 하지만, 우리는 볼륨 설정을 해줬기 때문에, 이전 컨테이너에서 생성한 test
데이터베이스가 접속과 동시에 생성되어 있는 것을 확인할 수 있었다.
Docker Compose 작성하기 💻
지난 글에서, 프로트엔드 서버와 백엔드 서버, DB 서버를 각각의 컨테이너로 만들어서 연동시켜봤는데, 이번에는 Docker Compose 파일을 작성하여 하나의 컨테이너에서 3개가 동시에 실행되도록 작성해본다.
프론트엔드 설정 ✅
1) 프론트엔드 프로젝트를 VS Code로 연 뒤 package.json
파일로 들어간뒤,
7번째 줄의 build 부분에 빌드 시 이미지( 이미지 이름 : frontend / 버전 : 1.0 ) 를
생성토록 아래와 같이 작성해준다.
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build && docker build --tag frontend:1.0 .",
"lint": "vue-cli-service lint"
},
2) nginx 이름의 폴더를 생성하여, default.conf 파일에 nginx 설정파일을 적어준다.
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location /api {
rewrite ^/api(.*)$ $1 break;
// 이 backend는 나중에 실행될 backend 도커 컨테이너의 IP를 말한다.
proxy_pass http://backend:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
alias /usr/share/nginx/html/;
try_files $uri $uri/ /index.html;
}
#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;
#}
}
2) 빌드 시 nginx 실행을 위해, Dockerfile을 생성하여 아래와 같이 작성해준다. 여기서
적어준 dist 폴더 안 경로들은 뷰 프로젝트를 배포하기 위해 빌드 시 생성되는 dist
폴더안의 모든 것들이다.
FROM nginx:latest // 사전에 pull 해논 nginx 이미지
ADD ./dist/css /usr/share/nginx/html/css
ADD ./dist/fonts /usr/share/nginx/html/fonts
ADD ./dist/img /usr/share/nginx/html/img
ADD ./js /usr/share/nginx/html/js
ADD ./dist/styles.css /usr/share/nginx/html/styles.css
ADD ./dist/logo.png /usr/share/nginx/html/logo.png
RUN rm -rf /usr/share/nginx/html/index.html
ADD ./dist/index.html /usr/share/nginx/html/index.html
RUN rm -rf /etc/nginx/conf.d/default.conf
ADD ./nginx/default.conf /etc/nginx/conf.d/default.conf
CMD ["nginx", "-g", "daemon off;"]
3) 다음으로 도커허브에서 프론트엔드 서버용 레포지토리를 생성한다.
➡ 나는 [레포지토리명]/fe
로 생성하였다.
4) VS Code 에서 터미널 창을 열고 프로젝트를 build 하여 이미지로 만든 후 생성한
레포지토리로 Push 해준다.
➡ build : docker build --tag [레포지토리명]/frontend:1.0 .
➡ push 방법 1 : docker push [레포지토리명]/frontend:1.0
➡ push 방법 2 : docker desktop의 이미지 탭에서 생성된 이미지 클릭 후 push
주의할점은 레포지토리에 같은 이름의 레포지토리가 생성되어 있지 않으면
Push to Hub
가 활성화 되어 있지 않는다.
참고용으로, 이미지 생성 시에 아래와 같은 에러가 발생했는데, 홈페이지 로고 파일 이름을 그림01.png
로 했었는데, 한글이 들어가다 보니깐 에러가 났던 것 같다. 파일명을 logo.png
로 하니깐 이미지가 잘 생성되었다.
하지만, 수업 시에도 동일하게 했었는데 그때 당시에는 에러 없이 잘 생성이 되었어가지고, 이부분은 확인이 필요할것 같다.
ERROR: failed to solve: Internal: rpc error: code = Internal desc = rpc error: code = Internal desc = header key "followpaths" contains value with non-printable ASCII characters
5) 이 다음부터는 docker build --tag 명령어가 아닌 npm run build
만 하면 수정된
부분만 반영되어 이미지가 생성된다.
이미지를 생성할때는 각각의 레이어들이 모여서 이미지가 생성되는데, 이것을
docker build --tag
명령어로 이미지를 생성하면 수정된 부분이 아닌 모든 이미지
레이어 위에 또 이미지 레이어를 쌓아가는 형식이 되어버린다. 내가 그렇게 해서
이미지를 5번 만드니, 레이어가 77개까지 쌓여있었다.
백엔드 설정 ✅
1) 백엔드 용 레포지토리를 생성해준다. : 나는 [레포지토리명]/be
로 생성
2) pom.xml
파일에 도커 플러그인을 추가해준다.
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.43.4</version>
<configuration>
<images>
<image>
<name>레포지토리명/be:1.0</name>
<build>
<dockerFileDir>${basedir}</dockerFileDir>
</build>
</image>
</images>
</configuration>
<executions>
<execution>
<id>docker-build</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
3) Dockerfile을 작성해준다.
FROM openjdk:11-jdk-slim-stretch // 자바 11버전을 사용하기 때문
COPY ./target/lonua-0.0.1-SNAPSHOT.jar lonua-0.0.1-SNAPSHOT.jar // 백엔드 서버 실행 jar 파일
CMD ["java", "-jar", "/lonua-0.0.1-SNAPSHOT.jar"] // 실행 명령어
4) resources
폴더 밑에 data.sql
파일을 생성 후 도커 컴포즈 실행 시 실행시킬
sql 쿼리문을 적어준다.
도커 컴포즈 파일 실행만으로도 모든 테이블과 테이블 안 데이터들이 들어가 있어야 하기때문에, 테이블 삭제, 생성 및 데이터 Insert 문을 테이블 간 연관관계를 고려하여 작성해주면 된다.
여기서 우리가 보통 application.yml
파일에 ddl-auto : create
로 설정하면, 기존에 있던 테이블들을 지우고 새로 생성하도록 설정하는 것이었는데, 도커 컴포즈로 실행 시에는 해당 설정이 동작을 하지 않기 때문에, ddl-auto : none
으로 설정해주고, 직접 테이블 삭제 및 생성하는 쿼리문을 작성해주는 것이다.
이것은, 데이터를 담아놨다면, MySQL Worknebch에서 Data Export를 한 뒤, 생성된 sql 파일을 열어보면 다 적혀져있다.
DROP TABLE IF EXISTS `Cart`;
CREATE TABLE `Cart` (
`cartIdx` int NOT NULL AUTO_INCREMENT,
`createdAt` varchar(255) NOT NULL,
`status` bit(1) NOT NULL,
`updatedAt` varchar(255) NOT NULL,
`Product_idx` int DEFAULT NULL,
`User_idx` int DEFAULT NULL,
PRIMARY KEY (`cartIdx`),
KEY `FKpogyyegw24ppobcvs41xrk714` (`Product_idx`),
KEY `FKgx3aftoes5r8y032qkhvd44v4` (`User_idx`),
CONSTRAINT `FKgx3aftoes5r8y032qkhvd44v4` FOREIGN KEY (`User_idx`) REFERENCES `User` (`userIdx`),
CONSTRAINT `FKpogyyegw24ppobcvs41xrk714` FOREIGN KEY (`Product_idx`) REFERENCES `Product` (`productIdx`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
5) application.yml
파일에서 작성한 data.sql 파일이 실행되도록 설정을 추가해준다.
spring:
sql:
init:
mode: always
6) Maven의 Lifecycle 에서 package
를 클릭하여, 이미지를 생성해준다.
7) docker desktop 에서 생성된 이미지를 레포지토리에 푸쉬해준다. ( 방법은 이전과 동일)
8) docker-compose.yml
파일 생성 후 아래와 같이 작성한다.
version: '3'
services:
frontend:
ports: // 프론트서버 포트번호 설정
- 8888:80
image: [레포지토리명]/fe:1.0
depends_on: // 백엔드가 실행되고 나서 실행토록 설정
- backend
backend:
image: [레포지토리명]/be:1.0
depends_on: // 백엔드 서버는 db 서버가 실행되고 나서 실행토록 설정
db:
condition: service_healthy
ports:
- 8080:8080
environment: // 환경 변수들 작성
APP_PASSWORD: dddddd
db:
image: mysql:latest
ports:
- 3306:3306
- 33060:33060
volumes:
- db-vol:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: qwer1234
MYSQL_DATABASE: test // DB 생성 시 test 데이터베이스를 생성토록 설정
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost","-pqwer1234" ]
interval: 10s
timeout: 5s
retries: 3
volumes:
db-vol:
driver: local
9) 도커 컴포즈 파일을 실행시키면, 프론트 서버, 백엔드 서버, DB 서버 총 3개의 컨테이너가
실행될 것이다.
프론트 서버 ( localhost:8888
) 로 접속해보면 정상적으로 접속이 될 것이고, 백엔드
서버와의 통신 및 DB에 넣어둔 데이터들도 정상적으로 보일 것이다.
이렇게 되면, 이 컴포즈 파일 하나만 있으면, 어떤 환경에서도 내가 설정한 서버환경을
구동하는것이 가능해진다.