Skip to main content

26. [BackEnd] docker compose 사용

docker compose는 단일 서버에서 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너 묶음으로 관리할 수 있는 도구입니다.

docker compose 작성하기


docker-compose.yaml 파일을 생성합니다.

이 곳에서 다양한 문서를 볼 수 있습니다.

service: 서비스 밑에 다양한태그들로 작성합니다.

image: 이미지

environment: 환경변수

services:
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=simple_bank
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- DB_SOURCE=postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable

위처럼 작성할 수 있고 주의할 점은 DB_SOURCE에서 아이피 대신 postgres를 사용해서 했습니다.

실행하기


docker compose up 

하면 됩니다.

db migrate 추가하기


start.sh

#!/bin/sh

set -e

echo "**run db migration**"
/app/migrate -path /app/migration -database "$DB_SOURCE" -verbose up

echo "***start the app***"
exec "$@"

알파인 리눅스라 bash가 없어서 /bin/sh사용해야 합니다.

set -e는 실행 실패 시 쉘스크립트 종료 하는 구문입니다.

/app/migrate .. 하는 부분이 migrate up 하는 부분이고

exec "$@"는 들어온 매개변수를 실행하는 역할입니다.

여담으로 exec "$@"가 아닌 echo "$@"로 작성해서 1시간을 버렸습니다.

Dockerfile

# Build stage
FROM golang:1.21-alpine3.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o main main.go
RUN apk add curl
RUN curl -L https://github.com/golang-migrate/migrate/releases/download/v4.16.2/migrate.linux-amd64.tar.gz | tar xvz

# Run stage
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/migrate ./migrate
COPY app.env .
COPY start.sh .
COPY db/migration ./migration

EXPOSE 8080
CMD ["/app/main"]
ENTRYPOINT ["/app/start.sh"]

도커 파일도 바뀐 부분이 있습니다.

기본적으로 alpine 리눅스에는 curl이 설치되어있지 않아서 apk add curl해야합니다.

migrate 설치하고 옮기고.. 마이그레이션 파일들도 옮기고 ENTRYPOINT로 start.sh을 실행할 수 있는데 이러면 CMD는 그저 start.sh로 매개변수로 넣는 역할로 변합니다. (ENTRYPOINT가 있다면)

다시 docker-compose 적용하려면


docker compose down 

해야 한다. 그러면 docker compose up으로 생긴 것들 삭제함

의존성 추가


postgres db가 올라오는 시간이 걸리기때문에 migrate 실패함.

이에 대한 의존성 추가하는 방법이 있다.

먼저 wait-for 스크립트를 다운로드 한다.

여기에서 다운로드하면 된다.

그리고 당연히 프로젝트 root path로 옮긴다.

Dockerfile

# Build stage
FROM golang:1.21-alpine3.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o main main.go
RUN apk add curl
RUN curl -L https://github.com/golang-migrate/migrate/releases/download/v4.16.2/migrate.linux-amd64.tar.gz | tar xvz

# Run stage
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/migrate ./migrate
COPY app.env .
COPY start.sh .
COPY wait-for.sh .
COPY db/migration ./migration

EXPOSE 8080
CMD ["/app/main"]
ENTRYPOINT ["/app/start.sh"]

그리고 복사를 하구요

docker-compose.yaml

services:
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=simple_bank
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- DB_SOURCE=postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable
depends_on:
- postgres
entrypoint: ["/app/wait-for.sh","postgres:5432","--","/app/start.sh"]
command: ["/app/main"]

여기에서 entrypoint를 넣었기 때문에 dockerfile의 entrypoint는 무시가되어서 command로 /app/main을 추가해야한다고 합니다.

하지만

docker-compose.yaml
services:
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=simple_bank
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- DB_SOURCE=postgresql://root:secret@postgres:5432/simple_bank?sslmode=disable
depends_on:
- postgres
links:
- postgres
Dockerfile
# Build stage
FROM golang:1.21-alpine3.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o main main.go
RUN apk add curl
RUN curl -L https://github.com/golang-migrate/migrate/releases/download/v4.16.2/migrate.linux-amd64.tar.gz | tar xvz

# Run stage
FROM alpine:3.18
WORKDIR /app
COPY --from=builder /app/main .
COPY --from=builder /app/migrate ./migrate
COPY app.env .
COPY start.sh .
COPY wait-for.sh .
COPY db/migration ./migration

EXPOSE 8080
CMD ["/app/main"]
ENTRYPOINT ["/app/wait-for.sh", "postgres:5432", "--", "/app/start.sh"]

이렇게 해도 되는거 같아요