yoncho`s blog

9. Dockerize a Restful API with Golang 본문

기술, 나의 공부를 공유합니다./Docker

9. Dockerize a Restful API with Golang

욘초 2023. 6. 22. 23:48

Env. :
Windows pc - version
Docker - version 23.0.5, build bc4487a
go - version go1.20.4 windows/amd64

 

Work Directory :
$GOPATH\bin
(*위 경로를 본 글에서 \bin 으로 표현하겠습니다.)

 

Work Flow

1. \bin 에서 Go module 초기화

2. \bin 에서 Restful API Go Example Code 작업 (main.go 생성)

3. \bin 에서 Dockerfile 작업 (dockerfile 생성)

4. \bin 에서 Dockerfile build 명령어 수행 (docker image 생성 완료)

5. 생성한 docker image로 docker container 실행 시켜서 Restful API 동작 테스트

 

 

1. 작업 디렉터리에서 Go module 초기화 및 필요한 module 설치

  • Go module 초기화
go mod init [MODULE NAME]

*작업 디렉터리에서 go file을 실행할 때 사용할 module 파일 초기화 해준다.
GOPATH 하위 디렉터리에서 go file을 생성하는게 아니여도 go.mod만 있으면 어디서든 go file을 실행시킬 수 있다.

  • 필요한 module 설치
go get github.com/gorilla/mux

*Restful api를 구현하기 위해 필요한 패키지

 

 

2. 작업 디렉터리에서 Restful API Go Example Code 작업

  • main.go 파일 생성
code main.go

*code : vs code를 실행시키는 명령어
사전에 실행 명령어를 설치함.

  • main.go 파일에 Restful API Example 코드 작성
package main

import (
	"encoding/json"
	"log"
	"net/http"
	"github.com/gorilla/mux"
)

// 사용자 모델 정의
type User struct {
	ID       string `json:"id,omitempty"`
	Username string `json:"username,omitempty"`
	Email    string `json:"email,omitempty"`
}

var users []User

// 사용자 목록 조회 핸들러
func GetUsers(w http.ResponseWriter, r *http.Request) {
	json.NewEncoder(w).Encode(users)
}

// 사용자 상세 조회 핸들러
func GetUser(w http.ResponseWriter, r *http.Request) {
	params := mux.Vars(r)
	for _, item := range users {
		if item.ID == params["id"] {
			json.NewEncoder(w).Encode(item)
			return
		}
	}
	json.NewEncoder(w).Encode(&User{})
}

// 사용자 생성 핸들러
func CreateUser(w http.ResponseWriter, r *http.Request) {
	params := mux.Vars(r)
	var user User
	_ = json.NewDecoder(r.Body).Decode(&user)
	user.ID = params["id"]
	users = append(users, user)
	json.NewEncoder(w).Encode(user)
}

// 사용자 삭제 핸들러
func DeleteUser(w http.ResponseWriter, r *http.Request) {
	params := mux.Vars(r)
	for index, item := range users {
		if item.ID == params["id"] {
			users = append(users[:index], users[index+1:]...)
			break
		}
	}
	json.NewEncoder(w).Encode(users)
}

func main() {
	// 라우터 초기화
	router := mux.NewRouter()

	// 사용자 목록 조회 API
	router.HandleFunc("/users", GetUsers).Methods("GET")

	// 사용자 상세 조회 API
	router.HandleFunc("/users/{id}", GetUser).Methods("GET")

	// 사용자 생성 API
	router.HandleFunc("/users/{id}", CreateUser).Methods("POST")

	// 사용자 삭제 API
	router.HandleFunc("/users/{id}", DeleteUser).Methods("DELETE")

	// 서버 실행
	log.Fatal(http.ListenAndServe(":8000", router))
}

 

3. 작업 디렉터리에 Dockerfile 작업 (dockerfile 생성)

  • Dockerfile 생성
code dockerfile

*Dockerfile은 “dockerfile”로 명명해줘야 빌드할 때 편하다.
만약 다른 이름으로 만들 경우, 따로 명칭에 대한 연결 작업을 해줘야한다.

 

  • Dockerfile에 main.go를 빌드 시켜 image로 만들기 위한 스크립트를 작성
FROM golang:latest

WORKDIR /

COPY go.mod .
COPY go.sum .

RUN go mod download

COPY . .

RUN go build -o main .

CMD ["./main"]

 

 

 

4. 작업 디렉터리에 Dockerfile build 명령 수행해서 image 생성하기

  • Build 명령어 수행 하기 전 현재 작업 디렉터리 구성을 확인
\bin> ls
dockerfile
go.mod
go.sum
main.go

*작업 디렉터리 안에 있는 파일 목록을 보면
go.mod : go 프로그램 내 종속성 관리
go.sum : go.mod에 종속성 정보가 추가될 때 생성
dockerfile : docker image를 만들기 위한 스크립트 파일
main.go : image로 만들기 위한 go 프로그램 (예 : Restful api example code)
* 참조 : https://yoongrammer.tistory.com/33

  • Dockerfile build 명령어 수행
docker build . -t test_restful_api:1.0

*docker build : dockerfile 빌드 명령어
. : 현재 디렉터리에서 진행
-t : 태그 및 이름 지정 (예 : test_restful_api:1.0)
test_restful_api:1.0 : image 이름 및 태그

  • 결과

이미지 생성 완료

 

docker 이미지 목록 확인 (test_restful_api : 1.0 이 생성됨을 확인)

 

 

5. 생성한 Image로 Container 생성해서 Restful API 동작 확인

  • 생성한 Image로 Container 동작 시키기
docker run --name restful_api_container -p 8000:8000 test_restful_api:1.0

*--name : container 이름을 지정
*-p 8000:8000 : Restful API Go Example 코드 상 8000번 포트를 열었기 때문에 8000번으로 연결해주었다.
앞에 8000은 Host, 뒤에 8000은 컨테이너의 연결할 포트 번호를 의미한다.
*test_restful_api:1.0 : 위에서 dockerfile로 생성한 image의 이름과 태그를 의미한다.

 

  • Restful API Example이 올라간 “restful_api_container” 이름의 Container 가 실행 중임. (*Postman으로 확인)

*서버 전체 사용자 목록 표시 ([GET] localhost:8000/users)

 

 

*POST로 객체 하나 서버로 전송 ([POST] localhost:8000/users/yoncho)

 

*서버 전체 사용자 목록 표시 ([GET] localhost:8000/users)

 

'기술, 나의 공부를 공유합니다. > Docker' 카테고리의 다른 글

8. Docker rmi  (0) 2023.06.22
7. Docker rm  (0) 2023.06.22
6. Docker Run (Create + Start)  (0) 2023.06.22
5. Docker Stop  (0) 2023.06.22
4. Docker Start  (0) 2023.06.22
Comments