ECR Cotainer 이미지를 업로드할 AWS 가상 환경에 리포지토리를 생성하고자 합니다. ECR 리포지토리를 사용해서 EKS에서 생성되는 Web Application에 대한 Golang Docker Image를 제공해야합니다.
이미지 Push (너무 Front, Back에 초점을 맞추기 보단, 2개의 Docker Image를 사용한다는 것에 초점을 맞춥니다.)
1. Front End
2. Back End
참고
- https://github.com/jimmahoney/golang-webserver
1. home.html
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<title>go server example</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script>
$(function(){ ajax_request() });
var ajax_handler = function(json){
/* debugging : */
/* alert(" typeof(json) = " + typeof(json) + "; json = " + json); *
/* the json data for /item/foo should be {"name":"foo","what":"item"} */
$("#the_span").html(json.name);
}
var ajax_request = function(){
/* see https://api.jquery.com/jQuery.get */
$.get("/item/foo", ajax_handler, "json");
}
</script>
</head>
<body>
<h1>go server example</h1>
<p>The ajax request says the name is '<span id="the_span">?</span>'.</p>
</body>
</html>
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"regexp"
"strconv"
)
func SetMyCookie(response http.ResponseWriter) {
// 응답에 간단한 쿠키를 추가합니다.
cookie := http.Cookie{Name: "testcookiename", Value: "testcookievalue"}
http.SetCookie(response, &cookie)
}
// /generic/ 형식의 URL에 응답합니다...
func GenericHandler(response http.ResponseWriter, request *http.Request) {
// HTTP 헤더에서 쿠키 및 MIME 유형을 설정합니다.
SetMyCookie(response)
response.Header().Set("Content-type", "text/plain")
// URL 및 POST 데이터를 요청에 구문 분석합니다.형태
err := request.ParseForm()
if err != nil {
http.Error(response, fmt.Sprintf("error parsing url %v", err), 500)
}
// 텍스트 진단을 클라이언트에 보냅니다.
fmt.Fprint(response, "FooWebHandler says ... \n")
fmt.Fprintf(response, " request.Method '%v'\n", request.Method)
fmt.Fprintf(response, " request.RequestURI '%v'\n", request.RequestURI)
fmt.Fprintf(response, " request.URL.Path '%v'\n", request.URL.Path)
fmt.Fprintf(response, " request.Form '%v'\n", request.Form)
fmt.Fprintf(response, " request.Cookies() '%v'\n", request.Cookies())
}
// html 홈 페이지로 URL/home에 응답합니다.
func HomeHandler(response http.ResponseWriter, request *http.Request) {
response.Header().Set("Content-type", "text/html")
webpage, err := ioutil.ReadFile("home.html")
if err != nil {
http.Error(response, fmt.Sprintf("home.html file error %v", err), 500)
}
fmt.Fprint(response, string(webpage))
}
// /item/의 URL에 응답합니다...
func ItemHandler(response http.ResponseWriter, request *http.Request) {
// HTTP 헤더에서 쿠키 및 MIME 유형을 설정합니다.
SetMyCookie(response)
response.Header().Set("Content-type", "application/json")
// 고객에게 다시 보낼 샘플 데이터입니다.
data := map[string]string{"what": "item", "name": ""}
// 양식의 URL이 /item/name이었습니까?
var itemURL = regexp.MustCompile(`^/item/(\w+)$`)
var itemMatches = itemURL.FindStringSubmatch(request.URL.Path)
// itemMatches는 정규식과 일치하는 것으로 캡처됩니다(예: ["/item/which", "which").
if len(itemMatches) > 0 {
// 네, 그러니 고객에게 JSON을 보내주세요.
data["name"] = itemMatches[1]
json_bytes, _ := json.Marshal(data)
fmt.Fprintf(response, "%s\n", json_bytes)
} else {
// 아니요, "페이지를 찾을 수 없습니다"를 보냅니다.
http.Error(response, "404 page not found", 404)
}
}
func main() {
port := 8080
portstring := strconv.Itoa(port)
// 두 개의 URL 패턴에 대한 요청 처리기를 등록합니다.
// (문서들은 '패턴'이 무엇인지 명확하지 않다.
// URL의 시작점인 것 같습니다. /로 끝납니다.).
// 보다 강력한 매칭 시스템을 보려면 gorilla/mux를 참조하십시오.
// "/" 패턴은 모든 요청 URL과 일치합니다.
mux := http.NewServeMux()
mux.Handle("/home", http.HandlerFunc(HomeHandler))
mux.Handle("/item/", http.HandlerFunc(ItemHandler))
mux.Handle("/generic/", http.HandlerFunc(GenericHandler))
// Start listing on a given port with these routes on this server.
// (I think the server name can be set here too , i.e. "foo.org:8080")
log.Print("Listening on port " + portstring + " ... ")
err := http.ListenAndServe(":"+portstring, mux)
if err != nil {
log.Fatal("ListenAndServe error: ", err)
}
}
cat << EOF > Dockerfile
FROM golang:1.12.0-alpine3.9
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go mod download
RUN go build -o main .
CMD ["/app/main"]
EOF
timezone=$(date "+%Y%m%d")
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com
docker build -t wsi-ecr-repo:front$timezone .
docker tag wsi-ecr-repo:front$timezone $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:front$timezone
docker push $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:front$timezone
사용자가 ECR 푸시 명령이 햇갈리다면 ECR을 생성하면 푸시 명령을 추천 해줍니다.
5. 결과(이 이미지를 가지고 Front Node에 적용해야합니다)
참고
- https://dev.to/erozedguy/ci-cd-pipeline-for-amazon-ecs-fargate-with-terraform-33na
package main
import (
"log"
"net/http"
"os"
"time"
)
func RequestLogger(targetHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
targetHandler.ServeHTTP(w, r)
// log request by IP address
requesterIP := r.RemoteAddr
log.Printf( // 이 부분이 출력 결과 값 지정해준다. 순서대로 결과 출력 아래 확인
"%s\t\t%s\t\t%s\t\t%v",
r.Method,
r.RequestURI,
requesterIP,
time.Since(start),
)
})
}
func worldskillsHandler(w http.ResponseWriter, r *http.Request) {
html := "worldskills" //이 부분은 이제 curl 요청을 했을 때 나오는 출력
_, err := w.Write([]byte(html))
if err != nil {
return
}
}
func main() {
logFileName := "/var/log/web.log" //Log file을 지정해주는 겁니다. 경로가 포함되도 상관X
logFile, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
defer func(logFile *os.File) {
err := logFile.Close()
if err != nil {
panic(err)
}
}(logFile)
// set log output destination
log.SetOutput(logFile)
mux := http.NewServeMux() //mux라는 라우터를 새로 생성
mux.HandleFunc("/worldskills", worldskillsHandler) // Curl 경로 지정, 함수명(위에)
// set request logger and run server
log.Fatal(http.ListenAndServe(":80", RequestLogger(mux)))
}
cat << EOF > Dockerfile
FROM golang:1.12.0-alpine3.9
RUN mkdir /app
ADD . /app
WORKDIR /app
RUN go mod download
RUN go build -o main .
CMD ["/app/main"]
EOF
timezone=$(date "+%Y%m%d")
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com
docker build -t wsi-ecr-repo:backend$timezone .
docker tag wsi-ecr-repo:backend$timezone $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:backend$timezone
docker push $AccountID.dkr.ecr.ap-northeast-2.amazonaws.com/wsi-ecr-repo:backend$timezone