Dockerfile을 이용한 도커 이미지 빌드
Dockerfile
도커 이미지를 빌드하는데 필요한 명령어를 순서대로 기술한 텍스트 파일
https://docs.docker.com/reference/dockerfile/
지시어(Instruction) | 의미 |
FROM | 베이스 이미지 지정 |
RUN | 베이스 이미지에 새로운 레이어를 추가해 커맨드를 실행하고, 결과를 빌드 이미지에 반영 |
CMD | 컨테이너를 시작할 때 실행할 커맨드를 설정 |
LABEL | 이미지에 레이블을 설정 |
EXPOSE | 컨테이너에서 공개하는 포트 번호 설정 |
ENV | 환경 변수 설정 |
ADD | 이미지에 파일 복사 (압축 파일의 경우 압축을 해제한 후 복사) |
COPY | 이미지에 파일 복사 |
ENTRYPOINT | 컨테이너를 시작할 때 실행할 커맨드 설정 |
VOLUME | 볼륨이 마운트될 위치를 설정 |
USER | 커맨드를 실행할 사용자 ID 설정 |
WORKDIR | 컨맨드를 실행할 작업 디렉터리를 설정 |
ARG | 빌드 시에만 사용되는 변수 설정 |
ONBUILD | 이 이미지를 베이스 이미지로 사용하여 이미지를 빌드할 때 실행할 커맨드 설정 |
STOPSIGNAL | 컨테이너를 중지시킬 때의 시그널 번호를 설정 |
HEALTHCHECK | 헬스체크를 위한 커맨드 설정 |
SHELL | 기본으로 사용할 쉘을 지정 |
Go 기반 컨테이너 애플리케이션을 개발
#1 작업 디렉터리 생성
mkdir c:\docker\go
cd c:\docker\go
code .
#2 소스 코드를 작성
c:\docker\go\main.go
/* 8080 포트로 HTTP 요청을 대기하다가, /로 요청이 들어오면 Hello Docker!!!를 응답 */
/* 프로그램의 진입점인 main 패키지를 지정 */
package main
/* 표준 입출력과 문자열 형식을 처리하는 Go 패키지,
로그를 출력하기 위한 패키지,
HTTP 서버와 클라이언트 관련 기능을 제공하는 패키지를 임포트 */
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("received request")
fmt.Fprintf(w, "Hello Docker!!")
})
log.Println("start server")
server := &http.Server{Addr: ":8080"}
if err := server.ListenAndServe(); err != nil {
log.Println(err)
}
}
개발 환경(본인 PC)에서 애플리케이션을 실행 및 동작 확인
#1 go 다운로드 및 설치
#2 애플리케이션을 실행 (다른 명령 프롬프트에서)
다른 명령 프롬프트에서 http://localhost:8080/ 으로 요청을 전달
#3 동일한 애플리케이션을 다른 서버(PC)에서 실행한다면, ... #1~#2 과정을 반복해야 함
⇒ 애플리케이션과 애플리케이션 실행에 필요한 환경을 묶어서 배포하는 것이 필요
⇒ 컨테이너화를 통해 가능
도커 이미지 생성
#1 Dockerfile 작성
c:\docker\go\Dockerfile
FROM golang:1.24.4 # 베이스 이미지를 지정 ⇒ docker.io/library/golang:1.24.4
RUN mkdir -p /docker/go # 베이스 이미지를 이용해 실행한 컨테이너 내부에 /docker/go 디렉터리를 생성
COPY main.go /docker/go/ # 호스트에 main.go 파일을 컨테이너 내부의 /docker/go 디렉터리 아래로 복사
CMD ["go", "run", "/docker/go/main.go"] # 만들어진 이미지를 컨테이너화했을 때 실행할 명령
#2 도커 이미지 빌드 및 확인
~~~~~~~~~~
테스트
main.go 파일의 내용을 변경(본인을 식별할 수 있는 내용을 추가)한 후 이미지를 빌드
/* 8080 포트로 HTTP 요청을 대기하다가, /로 요청이 들어오면 Hello Docker!!!를 응답 */
/* 프로그램의 진입점인 main 패키지를 지정 */
package main
/* 표준 입출력과 문자열 형식을 처리하는 Go 패키지,
로그를 출력하기 위한 패키지,
HTTP 서버와 클라이언트 관련 기능을 제공하는 패키지를 임포트 */
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("received request")
fmt.Fprintf(w, "Hello Docker ^^!!")
})
log.Println("start server")
server := &http.Server{Addr: ":8080"}
if err := server.ListenAndServe(); err != nil {
log.Println(err)
}
}
새롭게 생성한 이미지를 이용해서 컨테이너를 실행(호스트 포트를 지정하지 않음)
myecho 컨테이너의 로그를 확인
컨테이너 애플리케이션 동작을 확인
--rm 은 컨테이너 stop시 자동으로 삭제되는 명령어
컨테이너 이미지를 도커 허브를 통해서 배포
이미지 이름에 repository 명을 본인의 도커 허브 사용자 명으로 변경
도커 허브에 등록
도커 허브에 이미지 등록을 확인
도커 허브에 등록된 이미지를 이용해서 컨테이너를 실행
서비스 동작 확인
다양한 플랫폼에 맞춰서 이미지를 빌드
컨테이너 내부에 명령어를 전달
컨테이너 쉘에 접속해서 작업
방법1. attach
키 입력이 동작하지 않음
해당 컨테이너가 호스트와 IO가 연결되어 있지 않기 때문
방법2. exec ... sh
쉘 실행을 종료
컨테이너 중지
실행 상태의 컨테이너를 조회
9090 포트로 서비스하고 있는 컨테이너를 중지
c:\docker\go> docker container ls
모든 상태의 컨테이너를 조회
정지 상태의 컨테이너를 재기동
--rm 옵션을 추가해서 실행 컨테이너를 중지 (myecho)
c:\docker\go> docker container ls -a ⇒ --rm 옵션을 추가해서 실행했기 때문에
해당 컨테이너는 중지와 동시에 삭제됨
여러 컨테이너를 삭제
a2133ffee83c -> 실행상태이므로 삭제 X
43b2ab722021 -> 중지상태이므로 삭제 O
컨테이너 상태와 무관하게 삭제
실행 여부와 관계 없이 강제로 삭제
여러 컨테이너를 실행 여부와 관계 없이 일괄적으로(강제로) 삭제 ⇒ 쉘 명령어를 이용 ⇒ 윈도우인 경우에는 파워 쉘에서
이미지 일괄 삭제
이미지를 조회
이미지 아이디만 조회
모든 이미지를 사용 여부와 무관하게 강제로 삭제
PS C:\Users\myanj> docker image rm -f $(docker image ls -q)
PS C:\Users\myanj> docker image ls
'Docker' 카테고리의 다른 글
Docker - 데이터 관리(Volume, Bind Mount) (1) | 2025.06.18 |
---|---|
Docker - RUN, CMD, ENTRYPOINT, EXPOSE 명령어 차이 (0) | 2025.06.17 |
Docker - 애플리케이션과 Apache 서버 이미지 만들기 (0) | 2025.06.17 |
Docker -i, -t, -d 옵션 (2) | 2025.06.16 |
Docker - 설치 & 컨테이너 실행 (0) | 2025.06.16 |
Docker 개념 (0) | 2025.06.16 |