📌Index
Go 란 구글(google)에서 개발한 언어로, 간결하고 신뢰성 있으며 효율적인 소프트웨어를
손쉽게 만들기 위한 오픈소스 프로그래밍 언어이다.
GoLang
은 간결한 의존성 해석 알고리즘을 통해서 다른 컴파일 언어에 비해 빌드가 빠르다는 장점이 있다.
✔️ 환경 구성
먼저 실습을 진행할 환경을 구성하자
디렉토리 만들기
$ mkdir golang
$ mkdir hello
$ cd /golang/hello
golang 설치하기
$ sudo apt install golang
go module 만들기
Golang
에서 module
은 Django
에서의 App
과 비슷한 개념이다.
$ go mod init hello
위의 명령을 실행하면 go.mod
파일이 생성되는데, 이렇게 설정하면 나중에 go build
, go run
할 때
파일을 따로 지정하지 않아도 된다.
go build .
와 같이 명령을 실행해도 go.mod
파일 정보를 읽어서 빌드하게 된다.
$ cat go.mod
module hello
go 1.13
✔️ Go 기초 실습
GoLang
은 컴파일 언어이지만, C와 달리 실행 파일을 만들지 않고도 바로 실행할 수 있다.
hello.go
package main
import "fmt"
func main() {
fmt.Println("hello go world")
}
hello.go
는 hello go wolrd
를 출력하는 간단한 코드이다.
go run
하면 실행파일 없이 바로 실행되는 것을 확인할 수 있다.
$ go run hello.go
hello go world
빌드를 하지 않는 것처럼 보일 수 있지만, 실제로는 이미 빠르게 빌드(컴파일)를 해서 실행한 것이다.
실행파일을 만들지 않고 바로 go run
하는 것은 일반적으로 테스트 시에 많이 사용하는 방식이다.
또한 앞서 module go.mod
를 생성했기 때문에 hello.go
파일을 지정하지 않고 go run .
으로 실행해도 정상적으로 진행된다.
$ go run .
그렇다면 이번에는 실행 파일을 만들어서 빌드 해보자!
-o
: output
$ go build -o hello hello.go
참고로, 아래에서 확인할 수 있듯이 GoLang
은 기본적으로 static build
된다.
$ file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=Xew94lip5of83edrsxSa/8XB7RY7GXYkuErfE3FlL/7s8zg7p_A_RGMeeC4DvB/bSosaz9uK6MWnPf89h5y, not stripped
hello
파일을 실행하면 정상적으로 출력되는 것을 확인할 수 있다.
$ ./hello
hello go world
이제 go
파일로 스크립트가 출력되는 이미지를 빌드해보자
먼저 다음과 같이 이미지를 빌드하기 위한 Dockerfile
을 작성한다
Dockerfile
FROM golang:1.18-buster AS gobuilder
COPY hello.go /app/hello.go
WORKDIR /app
RUN go build -o hello hello.go
FROM scratch
COPY --from=gobuilder /app/hello /
CMD ["/hello"]
docker build
를 통해 gohello
이미지를 빌드한다.
$ docker build -t gohello .
그리고 해당 이미지를 docker run
하면 hello go world
가 잘 출력되는 것을 확인할 수 있다
$ docker run gohello
hello go world
✔️ Web Application 만들기
Writing Web Applications을 따라 HTTP Web
을 만들어보자
먼저 실습을 진행할 환경(디렉토리)를 만든다.
$ mkdir goweb
$ cd goweb
그 다음 http
모듈을 만들자
$ go mod init http
그리고 다음과 같이 goweb.go
파일을 작성하자.
goweb.go
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
파일 내용 설명
import
는 패키지를 추가하는 부분으로,net/http
패키지는 웹앱을 만들 때 사용하는 패키지http.HandlFunc("/", handler)
:/
에 접속하면handler
함수를 실행하라는 의미fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
:/
뒤의 첫번째 요소(변수)를%s
에 넣어서 출력
참고) go fmt
: terraform fmt
처럼 파일들을 포맷팅하는 방법
go run
명령을 실행하여 테스트해보자
$ go run .
설정한 포트로 접속했을 때 잘 실행되는 것을 확인할 수 있다
✔️ Go App으로 Docker image 만들기
앞선 실습에서 작성한 goweb.go
으로 docker 이미지를 빌드해볼 예정이다.
먼저 이미지를 만들기 위한 Dockerfile
을 아래와 같이 작성한다.
Dockerfile
FROM golang:1.18-buster AS gobuilder
ENV CGO_ENABLED 0
COPY . /app
WORKDIR /app
RUN go build .
FROM scratch
COPY --from=gobuilder /app/goweb /
CMD ["/goweb"]
다음으로 이미지를 build하고 실행해보자
$ docker build -t goweb .
$ docker run -d -p 80:8080 goweb
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fd13bf97af3 gogin "/gogin" 28 seconds ago Up 27 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp dreamy_blackwell
접속 확인
📋 multistage-build 해보기
multistage-build
는 하나의 도커파일에 2개의 FROM이 있는 형식이다.
먼저 .dockerignorefile
을 작성하자
.dockerignorefile
이 무엇인지 모른다면? 👉 .dockerignorefile 설명
.dockeerignorefile
goweb
.dockerignore
Dockerfile
다음으로 multistage-build 형식의 이미지 빌드를 위한 Dockerfile
을 작성하자
Dockerfile
FROM golang:1.18-buster AS gobuilder
ENV CGO_ENABLED 0 #CGO Disable
COPY . /app
WORKDIR /app
RUN go build .
FROM scratch
COPY --from=gobuilder /app/goweb /
CMD ["/goweb"]
ENV CGO_ENABLED 0
: CGO Disable을 의미하는 것으로, Go 라이브러리 내부는 C 구조체를 참조하는 것이 있는데,Scratch
이미지는 아무것도 없기 때문에 C 관련된 기능을 꺼줘야 정상적으로 작동함
이제 이미지를 빌드하고 실행해보자
$ docker build -t goweb .
$ docker run -d -p 80:8080 goweb
d3d822b3ac86908913fcc691ce2b093460f65606a822be18c197c611b02409cb
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3d822b3ac86 goweb "/goweb" 3 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp agitated_chatterjee
정상적으로 실행되고 있는 것을 확인할 수 있고, 접속을 시도해보자
확인완료!
✔️ Docker에 Gin 배포하기
Gin 은 GoLang에서 가장 많이 사용하는 웹 프레임워크이다.
디렉토리 만들기
$ mkdir ~/golang/gogin
$ cd ~/golang/gogin
$ go mod init gogin
다음으로 아래와 같이 go
파일을 작성한다.
참고) golang
은 공식적인 패키지 서버가 없고 github
등 인터넷에서 가져오게된다.
gogin.go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
패지키 목록을 파일로 만들자. pip3 freeze
와 동일한 명령어이다.
$ go mod tidy
그러면 go.sum
파일이 생성되고, 이 파일은 requirements.txt
파일과 비슷하다고 보면 된다.
여기에는 패키지 목록이 저장되어있다.
$ cat go.sum
참고로 gin은 기본적으로 홈 디렉토리의 go/pkg/
에 설치된다.
다음으로 이미지 빌드를 위한 Dockerfile
을 만들자
Dockerfile
FROM golang:1.18-buster AS gobuilder
ENV CGO_ENABLED 0
COPY . /app
WORKDIR /app
RUN go build -o gogin .
FROM scratch
COPY --from=gobuilder /app/gogin /
CMD ["/gogin"]
EXPOSE 8080
이제 gogin
이미지를 빌드하자.
build
를 할 때 go.sum
파일이 있으면 알아서 읽어오기 때문에 pip install
과 같은 별도의 작업이 필요 없다.
아래와 같이 실행하면 자동으로 go.sum
에서 외부 패키지 목록을 읽어와 다운받는다.
$ docker build -t gogin .
이미지 gogin
으로 컨테이너를 실행하자
$ docker run -d -p 80:8080 gogin
접속 확인
$ curl 192.168.100.100/ping