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
# 해당 사이트: 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"]
FROM golang:latest
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN chmod +x /usr/src/app/*
CMD ["/usr/src/app/run"]
FROM amazonlinux:2
RUN mkdir app
WORKDIR /app
COPY . /app
RUN chmod +x /app/*
CMD ["/app/run"]
FROM amazonlinux:2
RUN mkdir /app
WORKDIR /app
COPY master/ /app #이 부분이 핵심입니다.
RUN chmod +x /app
ENTRYPOINT ["/app/run"]
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 이미지
라고 합니다.FROM scratch
ADD ./hello /hello
CMD ["/hello"]
💡 결과는 Hello에 대한 파일에 크기만 Docker Volume에서 사용되고, scratch에 크기는 0B가 출력됩니다.
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로 접근
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
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는 컨테이너를 실행하면 쉘 스크립트가 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 즉, 실행해주도록 하자