개발 관련 시리즈에서 Docker 웹 애플리케이션 개발자를 위한 컨테이너에 대해 다뤘을 때, 저는 이미 Couchbase 서버 컨테이너와 함께 Java 및 Node.js 애플리케이션을 컨테이너로 배포하는 방법을 살펴본 적이 있습니다. 이번에는 Golang 웹 애플리케이션을 Docker 컨테이너와 함께 배포하면 멋질 것이라고 생각했습니다. 카우치베이스.
이 과정은 이전 튜토리얼에서 이미 설명한 것과 매우 유사하지만 살펴볼 가치가 있습니다. 이전 튜토리얼에서 URL 단축 서비스를 주제로 설명했던 애플리케이션을 컨테이너화하는 방법을 살펴보겠습니다.
관심이 있으시다면 다음을 확인해 보세요. Docker를 사용하여 Couchbase 웹 애플리케이션으로 컨테이너화된 Java 배포하기 그리고 카우치베이스 웹 애플리케이션으로 Node.js를 도커 컨테이너로 배포하기를 클릭합니다.
요구 사항
이 가이드를 성공적으로 사용하기 위해 충족해야 하는 종속성은 하나뿐입니다. 호스트 머신에 Docker가 설치되어 있어야 합니다. Docker 엔진의 장점인 Golang이나 Couchbase Server를 설치할 필요는 없습니다.
꼭 그럴 필요는 없지만 해당 애플리케이션에 익숙해지는 것이 좋습니다. 애플리케이션의 코드에 대해 알아보려면 제가 작성한 튜토리얼을 참조하세요, Golang 및 Couchbase NoSQL로 URL 단축기 만들기.
Golang 애플리케이션을 위한 Docker 프로젝트 설정하기
애플리케이션의 소스 코드와 번들링할 내용은 아래에서 확인할 수 있습니다. 다음과 같은 Go 소스 코드 파일로 저장해야 합니다. main.go.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
패키지 메인 가져 오기 ( "encoding/json" "log" "net/http" "os" "time" "github.com/couchbase/gocb" "github.com/gorilla/mux" "github.com/speps/go-hashids" ) 유형 MyUrl 구조체 { ID 문자열 `json:"id,omitempty"` LongUrl 문자열 `json:"longUrl,omitempty"` ShortUrl 문자열 `json:"shortUrl,omitempty"` } var bucket *gocb.Bucket var bucketName 문자열 func ExpandEndpoint(w http.ResponseWriter, req *http.Request) { var n1qlParams []인터페이스{} query := gocb.NewN1qlQuery("SELECT `" + bucketName + "`.* FROM `" + bucketName + "` WHERE shortUrl = $1") 매개변수 := req.URL.Query() n1qlParams = append(n1qlParams, params.Get("shortUrl")) rows, _ := bucket.ExecuteN1qlQuery(query, n1qlParams) var 행 MyUrl 행.하나(&row) json.NewEncoder(w).Encode(행) } func CreateEndpoint(w http.ResponseWriter, req *http.Request) { var url MyUrl _ = json.NewDecoder(req.Body).Decode(&url) var n1qlParams []인터페이스{} n1qlParams = append(n1qlParams, url.LongUrl) query := gocb.NewN1qlQuery("SELECT `" + bucketName + "`.* FROM `" + bucketName + "` WHERE longUrl = $1") rows, err := bucket.ExecuteN1qlQuery(query, n1qlParams) if err != nil { w.WriteHeader(401) w.Write([]byte(err.Error())) 반환 } var 행 MyUrl 행.하나(&row) if row == (MyUrl{}) { hd := hashids.NewData() h := hashids.NewWithData(hd) now := time.Now() url.ID, _ = h.Encode([]int{int(now.Unix()})) url.ShortUrl = "http://localhost:12345/" + url.ID bucket.Insert(url.ID, url, 0) } else { URL = 행 } json.NewEncoder(w).Encode(url) } func RootEndpoint(w http.ResponseWriter, req *http.Request) { 매개변수 := mux.Vars(req) var url MyUrl bucket.Get(params["id"], &url) http.Redirect(w, req, url.LongUrl, 301) } 함수 main() { 라우터 := mux.NewRouter() cluster, _ := gocb.Connect("couchbase://" + os.Getenv("COUCHBASE_HOST")) bucketName = os.Getenv("COUCHBASE_BUCKET") 버킷, _ = cluster.OpenBucket(bucketName, "") 라우터.핸들펀크("/{id}", 루트엔드포인트).메서드("GET") 라우터.핸들펀크("/expand/", ExpandEndpoint).메서드("GET") 라우터.핸들펀크("/create", CreateEndpoint).메서드("PUT") log.Fatal(http.ListenAndServe(":12345", 라우터)) } |
위의 코드와 주제에 대한 이전 튜토리얼의 유일한 차이점은 os.Getenv("COUCHBASE_HOST")
그리고 os.Getenv("COUCHBASE_BUCKET")
명령을 추가합니다. 이렇게 하면 애플리케이션에 하드코딩하지 않고 환경 변수를 통해 컨테이너 런타임에 Couchbase 연결 정보를 정의할 수 있습니다.
카우치베이스 서버가 실행 중이라면 다음을 수행하여 웹 애플리케이션을 시작할 수 있습니다:
1 |
환경설정 COUCHBASE_HOST=localhost COUCHBASE_BUCKET=기본값 go 실행 *.go |
물론 프로젝트는 여러분의 $GOPATH에서 액세스할 수 있지만 http://localhost:12345 코드에 정의된 대로.
여기서 목표는 이 프로젝트를 로컬에서 실행하는 것이 아니라 Docker 컨테이너를 통해 실행하는 것입니다. 프로젝트를 실행하기 위해 도커파일 파일 옆에 있는 main.go 파일 또는 다른 이름으로 부르세요. 그리고 도커파일 파일에는 다음이 포함되어야 합니다:
1 2 3 4 5 6 7 8 9 10 11 12 |
FROM 골랑:알파인 RUN apk 업데이트 && apk 추가 git COPY . /go/src/app/ WORKDIR /go/src/app RUN go get -d -v RUN go 설치 -v CMD ["app"] |
기본적으로는 Docker용 공식 Golang Alpine Linux 이미지를 사용하겠지만 커스터마이징할 것입니다. 빌드 시간 동안 Git을 설치하여 main.go 파일에 있는 프로젝트 종속성을 이미지에 설치하여 가져오기
섹션을 클릭하고 애플리케이션을 설치합니다. 런타임에 설치된 애플리케이션을 실행합니다.
커스텀 도커 블루프린트에서 이미지를 빌드하려면 다음을 실행합니다:
1 |
도커 빌드 -t 골랑 프로젝트 . |
모든 컴파일 시간 단계가 완료되면 다음과 같이 됩니다. 골랑 프로젝트
도커 이미지. 이 이미지를 실행하기 전에 Couchbase에 대해 걱정해야 합니다. 컨테이너 외부에서 Couchbase를 실행할 수는 있지만, 그렇게 하면 무슨 재미가 있을까요?
사용자 지정 카우치베이스 서버 도커 이미지 만들기
골랑과 마찬가지로 공식 도커 이미지는 다음과 같은 용도로 존재합니다. 카우치베이스 서버. 완벽하게 수용 가능한 솔루션이지만 자동화된 솔루션은 아닙니다. 즉, 컨테이너가 시작된 후 데이터베이스를 수동으로 구성해야 합니다. 우리는 이를 피하고 싶을 것입니다.
대신 컴퓨터 어딘가에 디렉터리를 만들고 도커파일 파일과 configure.sh 파일을 생성합니다. 구성 스크립트를 실행할 Docker 블루프린트를 만들 계획입니다.
열기 도커파일 파일을 열고 다음을 포함하세요:
1 2 3 4 5 |
카우치베이스에서 COPY configure.sh /opt/couchbase CMD ["/opt/couchbase/configure.sh"] |
기본적으로 스크립트를 기본 이미지에 복사하고 실행하는 것뿐입니다. 진짜 마법은 스크립트 내부에서 일어납니다.
열기 configure.sh 파일을 열고 다음을 포함하세요:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
set -m /entrypoint.sh 카우치베이스 서버 & 수면 15 curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=512 -d indexMemoryQuota=512 curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2cn1ql%2Cindex curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=$COUCHBASE_ADMINISTRATOR_USERNAME -d password=$COUCHBASE_ADMINISTRATOR_PASSWORD curl -i -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/settings/indexes -d 'storageMode=memory_optimized' curl -v -u $COUCHBASE_ADMINISTRATOR_USERAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/pools/default/buckets -d name=$COUCHBASE_BUCKET -d bucketType=couchbase -d ramQuotaMB=128 -d authType=sasl -d saslPassword=$COUCHBASE_BUCKET_PASSWORD 수면 15 curl -v http://127.0.0.1:8093/query/service -d "statement=`$COUCHBASE_BUCKET`에 주 인덱스 만들기" fg 1 |
Couchbase Server에는 스크립트를 통해 구성 마법사를 완료할 수 있는 RESTful 인터페이스가 있습니다. 위의 명령은 인스턴스 사양 및 서비스, 관리 자격 증명 및 버킷을 정의합니다.
다음과 같은 사항을 확인할 수 있습니다. $COUCHBASE_ADMINISTER_USERNAME
를 사용할 수 있습니다. Golang 애플리케이션에서와 마찬가지로 환경 변수를 활용하여 이미지에 값을 하드코딩할 필요가 없도록 하고 있습니다. 이러한 값은 컨테이너 배포 중에 정의할 수 있습니다.
카우치베이스 서버 컨테이너 프로비저닝에 대한 자세한 내용은 다음 문서에서 확인할 수 있습니다. 이전 기사 에 대한 글을 썼습니다.
마지막으로 이 사용자 정의 Couchbase Server 이미지를 빌드할 수 있습니다. Docker 셸에서 다음을 실행합니다:
1 |
도커 빌드 -t couchbase-custom . |
위의 명령을 실행하면 카우치베이스 커스텀
이미지.
컨테이너화된 마이크로서비스 배포하기
구축한 이미지를 배포하는 방법에는 몇 가지가 있습니다. 여기서는 그 중 두 가지 방법을 살펴보겠습니다.
이미지에 대해 알고 있는 정보를 바탕으로 다음 명령어를 사용하여 컨테이너를 배포할 수 있습니다:
1 2 3 4 5 6 7 8 9 |
도커 실행 -d \ -p 8091-8093:8091-8093 \ -e COUCHBASE_ADMINISTRATOR_USERNAME=관리자 \. -e COUCHBASE_ADMINISTRATOR_PASSWORD = 비밀번호 \. -e COUCHBASE_BUCKET=기본값 \ -e COUCHBASE_BUCKET_PASSWORD= \ --network="docker_default" \. --이름 카우치베이스 \ 카우치베이스 커스텀 |
위의 명령은 필요한 포트를 호스트 운영 체제에 매핑하면서 카우치베이스 서버를 배포합니다. 명령과 함께 각 환경 변수를 전달하고 운영 네트워크를 정의하고 있습니다. 데이터베이스와 애플리케이션이 모두 동일한 컨테이너 네트워크에 있어야 하므로 네트워크가 중요합니다.
1 2 3 4 5 6 7 |
도커 실행 -d \ -p 12345:12345 \ -e COUCHBASE_HOST=couchbase \ -e COUCHBASE_BUCKET=기본값 \ --network="docker_default" \. --이름 골랑 골랑 프로젝트 |
위의 명령은 올바른 포트를 다시 매핑하면서 Golang 이미지를 배포합니다. 호스트의 경우 다음을 사용하고 있음을 알 수 있습니다. 카우치베이스
는 실제로 다른 컨테이너의 이름입니다. 컨테이너 이름은 호스트 이름 역할도 합니다.
방금 보신 명령은 제 생각에는 매우 수동적인 방법입니다. 대신 도커 컴포즈 파일로 처리할 수 있습니다.
만들기 docker-compose.yml 파일을 컴퓨터 어딘가에 다음과 같이 저장합니다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
버전: '2' 서비스: 카우치베이스: 이미지: 카우치베이스 커스텀 포트: - 8091:8091 - 8092:8092 - 8093:8093 환경으로 이동합니다: - COUCHBASE_ADMINISTRATOR_USERNAME=관리자 - COUCHBASE_ADMINISTRATOR_PASSWORD=비밀번호 - COUCHBASE_BUCKET=기본값 - 카우치베이스_버킷_암호= 골랑: 이미지: 골랑 프로젝트 포트: - 12345:12345 환경으로 이동합니다: - COUCHBASE_HOST=couchbase - COUCHBASE_BUCKET=기본값 다시 시작: 항상 |
작성 파일의 모든 항목은 동일한 네트워크에 있습니다. 각 서비스를 배포하려면 다음을 실행합니다:
1 2 |
도커-컴포지트 실행 -d --service-ports 카우치베이스 도커-컴포지트 실행 -d -서비스-포트 골랑 |
Docker Compose에 익숙하다면 다음 사항에 익숙할 것입니다. 도커-컴포지트 업
를 사용할 수 있지만 여기서는 사용할 수 없습니다. 카우치베이스 서버에는 준비가 되었다는 것을 알려주는 메커니즘이 없으므로 구성되기 전에 Golang 애플리케이션이 연결을 시도하지 않기를 원합니다. 컨테이너 배포에 있어서는 확실히 큰 문제가 아닙니다.
결론
방금 Golang 마이크로서비스를 생성하는 방법을 살펴보셨습니다. Docker 컨테이너와 통신하는 컨테이너로, 또한 Docker 컨테이너 내에서 실행됩니다. 애플리케이션을 Docker 이미지로 전환하면 배포하려는 환경에 대해 걱정할 필요가 없으므로 배포하기가 매우 쉬워집니다. Docker 엔진만 사용할 수 있다면 애플리케이션을 배포할 수 있습니다. 이에 대한 유용한 예는 다음과 같습니다. 컨테이너의 지속적인 배포 Jenkins를 사용합니다.
Java 애플리케이션을 컨테이너화하는 방법을 알고 싶으신가요? 확인해 보세요. 이 튜토리얼 제가 썼어요. Node.js 애플리케이션을 컨테이너화하기 위한 튜토리얼도 있습니다. 여기.
Couchbase와 함께 Golang을 사용하는 방법에 대한 자세한 정보가 필요하신가요? 다음을 확인하세요. 카우치베이스 개발자 포털 에서 문서와 예제를 확인하세요.