똑같은 삽질은 2번 하지 말자
Docker 이미지를 개발용, 배포용으로 따로 작성하는 방법 본문
개요
배포할 때 배포용으로 Dockerfile을 수정하고 있는 나 자신이 한심해서 커맨드 하나로 개발용 이미지 배포용 이미지를 따로 따로 작성하는게 가능한 방법을 찾아보자.
개발용 배포용 두가지의 docker-compose를 작성
지금 상황은 개발을 할때는 DB와 Backend는 컨테이너로 가동시키고 있고 프론트의 경우에는 직접 로컬에서 가동시키고 있다.
( 이렇게 한 이유가 배포를 할때 중간에 프록시 서버를 두고 프론트 환경을 운용하고 있는데 이 프록시 서버와 프론트 서버의 설정 부분에서 개발용을 따로 설정하는게 귀찮아서 개발을 진행할때는 프론트 쪽 컨테이너는 아예 작동을 안시키고 있다. )
이래저래 구글링과 ChatGPT한테 물어본 결과 그냥 docker-compose파일을 두개 작성해서 관리하는게 편하겠다는 결론?에 도달했다. 그래서 바로 작성을 해보고자 한다!
배포용 docker-compose-prod.yml
version: "3"
services:
frontend-proxy:
image: nginx:1.18.0
ports:
- "8080:80"
restart: always
volumes:
- "./nginx/frontend-proxy.conf:/etc/nginx/nginx.conf"
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: prod
ports:
- "3000:3000"
db:
platform: linux/x86_64 # M1은 5.7 설치를 위해 이렇게 해야한다.
image: mysql:5.7
# command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: hwblog
MYSQL_USER: ghw
MYSQL_PASSWORD: heewon
volumes:
- .dbdata:/var/lib/mysql
- ./my.cnf:/etc/mysql/conf.d/my.cnf
ports:
- 3306:3306
backend:
build:
context: ./backend
dockerfile: Dockerfile
target: prod
ports:
- "5050:5050"
volumes:
- ./backend:/app
depends_on:
- db
command:
- bash
- -c
- |
chmod +x /wait-for-it.sh
/wait-for-it.sh db:3306 -t 10
go run main.go
- build 부분을 보면 Dockerfile을 지정하면서 target: prod를 하고 있는데 이게 무엇을 의미하는지는 곧 작성할 Dockerfile에서 알 수 있다.
- docker-compose -f docker-compose-prod.yml up 으로 파일 지정을 하면서 docker-compose 커맨드를 사용할 수 있기때문에 이런 코맨드를 이용해서 파일지정을 하자
backend/Dockerfile
FROM golang:1.18 as dev
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /
RUN curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
CMD ["air"]
FROM golang:1.18 as prod
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /
- FROM 행의 말단부분에 as dev, as prod로 각각 2개의 이미지가 작성되어 있는데 이게 위의 docker-compose의 build 부분의 target과 연결되는 부분이다.
frontend/Dockerfile
FROM node:16.13.2-alpine as dev
WORKDIR /app
COPY ./package.json ./
COPY ./yarn.lock ./
RUN yarn
COPY . .
CMD ["yarn", "dev"]
FROM node:16.13.2-alpine as prod
WORKDIR /app
COPY ./package.json ./
COPY ./yarn.lock ./
RUN yarn
COPY . .
RUN yarn build
CMD ["yarn", "start"]
아 그리고 개발용 docker-compose.yml은
version: "3"
services:
db:
platform: linux/x86_64 # M1은 5.7 설치를 위해 이렇게 해야한다.
image: mysql:5.7
# command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: hwblog
MYSQL_USER: ghw
MYSQL_PASSWORD: heewon
volumes:
- .dbdata:/var/lib/mysql
- ./my.cnf:/etc/mysql/conf.d/my.cnf
ports:
- 3306:3306
backend:
build:
context: ./backend
dockerfile: Dockerfile
target: dev
ports:
- "5050:5050"
volumes:
- ./backend:/app
depends_on:
- db
- 이건 그냥 docker-compose up으로 실행해도 default로 docker-compose.yml이 지정되기 때문에 간단하게 코맨드를 두들기면 된다.
- 역시 target: dev 부분은 backend/Dockerfile의 as dev 부분의 이미지를 가리키고 있다.
이런식으로 개발용 배포용 컨테이너를 나눌 수 있다. 더 좋은 방법도 많을 수 있겠지만 나는 이런식으로 하고 있다!
Comments