application.properties에 데이터베이스 주소와 비밀번호등을 올린 후 깃허브에 올리면 안되지 않나?
디비 교수님이 강조한 보안의 중요성
(지난 프로젝트에서 내가 얼마나 부족했던지 알게 된 부분이다. 각종 비밀번호가 깃허브에 올라가있다.. 그 이외에도 모종의 이유로 레포지토리를 private 해놓을 수 밖에 없었다)
그래서 Docker를 활용해 Mysql과 환경변수를 사용하기 위한 과정을 기록해보려고 한다.
Docker 홈페이지에서 다운로드 하고 다음 명령어로 설치를 확인한다.
$ docker -v
Docker version 27.4.0, build bde2b89
$ docker pull mysql
latest: Pulling from library/mysql
0b9dc7ad7f03: Download complete
a841bff36f3c: Download complete
1f87d67b89c6: Download complete
80ba30c57782: Download complete
5e49e1f26961: Download complete
cb5a6a8519b2: Download complete
570d30cf82c5: Download complete
ced670fc7f1c: Download complete
2c0a233485c3: Download complete
cd0d5df9937b: Download complete
Digest: sha256:0255b469f0135a0236d672d60e3154ae2f4538b146744966d96440318cc822c6
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 0255b469f013 3 months ago 828MB
$ docker run --name <컨테이너명> -e MYSQL_ROOT_PASSWORD=<rootPassword> -d -p 3306:3306 mysql:latest
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3cc3d3f49058 mysql:latest "docker-entrypoint.s…" 10 seconds ago Up 8 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp jpaUse1
포트 충돌 에러
처음 Docker를 깔고 포트를 연결할때는 기존의 컴퓨터에 깔려있는 MYSQL의 3306포트와 충돌이 발생하여 에러가 발생했다.
docker Error invoking remote method 'docker-start-container': Error: (HTTP code 500) server error - Ports are not available: exposing port TCP 0.0.0.0:3306 -> 0.0.0.0:0: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
$ netstat -ano | findstr 3306
결과값에서 pid = 6868임을 알 수 있었다
$ tasklist | findstr 6868
으로 어떤 프로세스가 3306 포트를 차지하고 있는지 알아보기
-> 기존에 컴퓨터에 깔려있던 MYSQL이 사용중
-> Docker를 사용하기 위해 3306 포트 비우기
$ taskkill /pid 6868 /f포트를 3306이 아닌 것으로 옮기는 방법도 있었는데 그 방법은 실행해보지 않았다
친구가 window + r -> services.msc를 입력하고 들어가 mysql을 중지 시키는 방법도 있다고 한다
Docker 컨테이너 내부에 mysql을 설치해서 사용해도 되지만, 컨테이너가 지워질 경우 데이터도 지워져버리고, 컨테이너에 의존적이기에 다른 컨테이너에서 사용이 어렵다는 단점이 있다.
그래서 volumn을 이용해 외부에 저장하는 방법이 선호된다고 한다.
위의 설치해둔 컨테이너를 지우고 진행하기 위해 다음과 같은 명령어로 시작된다.
앱에서 지우는 것이 훨씬 쉽다
$ docker stop <컨테이너명>
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3cc3d3f49058 mysql:latest "docker-entrypoint.s…" 33 minutes ago Exited (0) 7 seconds ago jpaUse1
$ docker rm <컨테이너ID>
루트디렉토리(src파일이 있는 위치)에 .env와 docker-compose.yml을 작성한다.
데이터베이스 비밀번호등 노출되면 안되는 코드를 .env파일에 적는다.
컨테이너에서 새로 mysql을 관리하기 때문에 루트비밀번호와 db이름등을 새로 설정하면 된다.
MYSQL_ROOT_PASSWORD = <루트비밀번호>
MYSQL_DATABASE = <db이름>
MYSQL_USER = <mysql유저>
MYSQL_PASSWORD = <유저비밀번호>
MySQL을 Docker 컨테이너로 실행하기 위한 docker-compose.yml 파일을 생성한다.
.env와 같은 디렉토리에 있으면 자동으로 docker-compose.yml에서 읽어들일 수 있다.
services:
mysql:
image: mysql:latest
restart: always
container_name: jpaUse1Container # 임의로 지정한 컨테이너 이름
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
위와 같이 작성하고 다음 명령어를 실행하니 에러가 발생했다.
$ docker-compose up -d
service "mysql" refers to undefined volume mysql-data: invalid compose project찾아보니 volumes 섹션을 새로 만들고 거기서 mysql-data를 정의해줘야 한다고 한다.
services:
mysql:
image: mysql:latest
restart: always
container_name: jpaUse1Container
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
driver: local
명령어를 실행해보니 container와 volume이 만들어졌다고 보인다. (앱에서도 확인 가능)
$ docker-compose up -d
[+] Running 1/1
✔ mysql Pulled 3.6s
[+] Running 3/3
✔ Network jpashop_default Created 0.2s
✔ Volume "jpashop_mysql-data" Created 0.0s
✔ Container jpaUse1Container Started