Dockerfile Example

Hoju·2022년 8월 25일
0

DC

목록 보기
3/3
  • Golang(간단한 golang 파일 컴파일 후 실행) → 만능 Golang Dockerfile
FROM golang:1.12.0-alpine3.9

RUN mkdir /app

ADD . /app -> Root 디렉터리에 있는 모든 것을 app 경로로 복사

WORKDIR /app

COPY go.mod ./

RUN go mod download -> 종속성을 가져오려면 이 go mod 다운로드 명령을 추가하세요.

RUN go build -o main . -> 현재 경로에 있는 go file을 컴파일

CMD ["/app/main"] -> 실행

또는

ENTRYPOINT ["/app/main/"]
CMD ["ap-northesat-2"]

실행
docker run -d --publish 80:80 world:latest
  • Golang2(멀티 스테이지 빌드)
# 해당 사이트: https://www.callicoder.com/deploy-containerized-go-app-kubernetes/
# 명령(1): go mod init github.com/callicoder/go-kubernetes
# 명령(2): go get github.com/gorilla/mux

FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
  • Golang 3 이 경우는 빌드 된 Golang 파일만 실행시키고자 할 때 하는 방안 입니다.
FROM golang:latest

WORKDIR /usr/src/app

COPY . /usr/src/app

RUN chmod +x /usr/src/app/*

CMD ["/usr/src/app/run"]
  • Amazon Linux Image 사용하기
FROM amazonlinux:2

RUN mkdir app
WORKDIR /app

COPY . /app
RUN chmod +x /app/*

CMD ["/app/run"]
  • local 디렉토리 파일 한꺼번에 옮기기
FROM amazonlinux:2

RUN mkdir /app
WORKDIR /app

COPY master/ /app #이 부분이 핵심입니다.

RUN chmod +x /app

ENTRYPOINT ["/app/run"]
  • Multi-stage build
FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
💡 --from=builder 옵션을 사용해서 개발 환경용(golang:latest as builder)에서 빌드한 실행 파일이 있는 경로를 지정해 local로 가져오도록 멀티 스테이지 빌드를 한 것입니다.

사용을 왜할까요? 즉, Docker image가 크기가 크면 용량 부족 에러를 겪을 수 있습니다. 그러나 멀티 스테이지 빌드를 적용하면, Golang:latest에서 빌드를 수행하고, 실행 바이너리를 alpine:latest로 전달하여 해당 이미지에서 동작하게 합니다. 그러한 점에서 alpine:latest는 이미 golang 이미지의 베이스 이미지이고, 미니멀한 이미지가 됩니다. 이러한 점에서 용량을 확 줄일 수 있습니다.

  • scratch Docker Image 사용: Docker에서 아무 것도 들어있지 않은 비어있는 베이스 이미지를 scratch 이미지라고 합니다.
FROM scratch
ADD ./hello /hello
CMD ["/hello"]
💡 결과는 Hello에 대한 파일에 크기만 Docker Volume에서 사용되고, scratch에 크기는 0B가 출력됩니다.
  • UserAdd Dockerfile
FROM golang:1.16.15

COPY ./match .
RUN chmod 777 ./match
RUN useradd -ms /bin/bash match
USER match
EXPOSE 8080
CMD ["./match"]

접근

docker exec -it [dockerids] bash #꼭 bash로 접근
  • Golang Build and Useradd Dockerfile
FROM golang:1.16.15

ENV GO111MODULE=on     CGO_ENABLED=0     GOOS=linux     GOARCH=amd64
WORKDIR /build
COPY ./HTTPserver.go .

RUN go build -o HTTPserver ./HTTPserver.go
RUN chmod 777 HTTPserver.go

RUN useradd -ms /bin/bash match
USER match
EXPOSE 8080
ENTRYPOINT ["/build/HTTPserver"]
접근
docker exec -it [Dockerids] bash
  • Golang Binary File(Linux) Run and Curl install
FROM golang:1.16.15

ENV GO111MODULE=on     CGO_ENABLED=0     GOOS=linux     GOARCH=amd64
WORKDIR /build
COPY ./match .
RUN chmod 777 match

RUN useradd -ms /bin/bash match
USER match
EXPOSE 8080
ENTRYPOINT ["/build/match"]
CMD ["yum install -y curl"]

Docker dumb-init 사용

왜 사용할까? Docker는 컨테이너를 실행하면 쉘 스크립트가 PID 1을 가져가게 되고, 해당 스크립트로 실행된 어플리케이션이 하위 PID받게됩니다. 즉, Docker Process를 종료 하더라도 고아 PID들이 남는다는 것이죠. 그래서 이 문제점을 해결하기 위해서 Docker dumb-init을 사용합니다.

DockerFile Example

FROM golang:latest as builder

WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
COPY ./1.sh /app

FROM alpine:latest
RUN apk add dumb-init
WORKDIR /root/
COPY --from=builder /app/main .
COPY --from=builder /app/1.sh .
EXPOSE 80

ENTRYPOINT ["/usr/bin/dumb-init", "--", "./1.sh"]
CMD ["./main"]

1.sh

#!/bin/sh

sleep 60

main.go

package main

import (
    "fmt"
    "net/http"
)

func health(w http.ResponseWriter, req *http.Request) {
    fmt.Fprint(w, "OK")
}

func main() {
    http.HandleFunc("/health", health)
    http.ListenAndServe(":80", nil)
}

참고 - https://www.hahwul.com/2022/08/06/docker-dumb-init/

만약 Application이 정상적으로 실행되지 않으면, 1.sh 파일에 ./main 즉, 실행해주도록 하자

profile
Devops가 되고 싶은 청소년

0개의 댓글