01 - Go Server를 설치하고 Docker에서 다시 로드합니다.

프로젝트 개요


이 글은 메모리 프로그램 설정에 관한'다부분'강좌의 시작이다.메모리 대상을 관리하는 데 사용되는 클라이언트 프로그램은 React/Typescript로 구축됩니다."memthings"백엔드 응용 프로그램을 관리하는 API는 노드/형식 스크립트를 사용하여 구축됩니다.사용자 계정과 인증은 별도의 응용 프로그램에서 관리되며 UI는 Vue에 내장되고 백엔드는 Go에 내장됩니다.이 모든 프로그램은 docker 용기에서 실행되도록 설정하고 Traefik가 제공하는 루트가 있는 같은 테스트 영역에 위탁 관리합니다.이 단락을 다 읽은 것을 축하합니다.아이고!
다음은 응용 프로그램의 개요와 우리가 구축하고자 하는 내용의 영상 프레젠테이션입니다!오늘 우리는 왼쪽 상단에 응용 프로그램을 구축하고 Traefik을 사용하여 이 용기에 정확한 경로를 요청할 것입니다.

본 강좌 동영상 버전을 좋아하는 사람들에게는
만약 잘 모르겠거나 제가 어떤 실수를 저질렀다면 Github 에서 기능 코드를 찾으십시오.
와모스!

디렉토리 만들기


참고로, 이 강좌가 끝날 때, 당신의 디렉터리 구조는 다음과 같습니다. (자술한 내용을 제외하고)

응용 프로그램을 구축하려면 모든 하위 항목과 응용 프로그램 범위의 프로필 (.env,docker-compose.yml) 을 포함하는 폴더를 만들어야 합니다.우리는 루트memrizr 폴더를 만들어서 이 점을 실현합니다. (프로그램을 만들 때 cutesy를 다시 맞춤법으로 쓰는 것이 매우 중요합니다.)Golang 응용 프로그램을 작성할 계정 디렉터리도 만들었습니다.
mkdir memrizr

cd memrizr

git init

mkdir account
다음에 루트 폴더에memrizr라는 작업 영역 파일을 만들 것입니다.코드 작업공간.VS 코드에서 파일을 만들 수 있습니다"multi-root" workspace.이 단계는 필요하지 않지만, GO 모듈 (GO.mod 파일을 사용하여 의존 항목을 표시) 의 Golang 프로젝트를 사용할 때 도움이 됩니다.Go 개발자 도구(언어 서버)가 Go에만 있기 때문입니다.mod 파일은 프로젝트의 루트 디렉터리에 있습니다.이것은 (다음 문제를 없앨 것이다) 있지만 이것은 어려운 임무인 것 같다.
우리는memrizr에 다음과 같은 내용을 추가했다.코드 작업공간 파일.그러면 계정 폴더와 루트 폴더가 작업공간으로 추가됩니다.루트 응용 프로그램 파일만 작업 영역에 추가하는 것을 더 좋아하지만 VS 코드는 현재 이 점을 지원하지 않습니다.이것requests to update을 보면 그들은 단기간 내에 이 목표를 실현하기를 원하지 않는 것 같다.에이, 아마도 너는 행운의 영혼이 2년 동안 읽은 선일지도 몰라. 상술한 도전이 존재하지 않는다면!
{
  "folders": [
    {
      "path": "./account"
    },
    {
      "path": "."
    }
  ]
}

Github 문제 main을 추가하는 중입니다.가다


현재, 우리는 Golang으로 작성된 웹 프레임워크와 http 공유기를 추가하기 위해 계정 폴더에 들어갈 것입니다.다음 명령을 실행할 때 모듈을 초기화할 때 Github 저장소 이름을 Github 저장소 이름으로 교체해야 합니다.
cd account

go mod init github.com/jacobsngoodwin/memrizr

go get -u github.com/gin-gonic/gin
현재, 우리는 주 go 파일을 만들 것입니다.이 파일에서 우리는:
  • 서로 다른 경로에 대한 http 요청을 처리하는 공유기를 만듭니다.현재, 우리는'/api/account'에 대한 단일 GET 루트와 첨부된 처리 함수를 만들었습니다.
  • 다음에 우리는 표준 Golang http 서버 구조를 만들고 우리가 방금 만든 gin 공유기를 응용합니다.
  • 마지막으로, 우리는 go 프로세스에서 서버를 실행합니다.코드의 링크에서 서버가 정상적으로 닫히는 것에 대한 더 많은 정보를 알 수 있습니다.본질적으로 코드는quit라는 채널을 만들어서 정지 신호 (예:ctrl-c) 를 탐지하는 데 사용합니다.<- quit 이 종료 신호를 받고 서버를 닫을 때까지 후속 코드를 막습니다.
  • package main
    
    import (
        "context"
        "log"
        "net/http"
        "os"
        "os/signal"
        "syscall"
        "time"
    
        "github.com/gin-gonic/gin"
    )
    
    func main() {
        // you could insert your favorite logger here for structured or leveled logging
        log.Println("Starting server...")
    
        router := gin.Default()
    
        router.GET("/api/account", func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{
                "hello": "world",
            })
        })
    
        srv := &http.Server{
            Addr:    ":8080",
            Handler: router,
      }
    
        // Graceful server shutdown - https://github.com/gin-gonic/examples/blob/master/graceful-shutdown/graceful-shutdown/server.go
        go func() {
            if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
                log.Fatalf("Failed to initialize server: %v\n", err)
            }
        }()
    
        log.Printf("Listening on port %v\n", srv.Addr)
    
        // Wait for kill signal of channel
        quit := make(chan os.Signal)
    
        signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    
        // This blocks until a signal is passed into the quit channel
        <-quit
    
        // The context is used to inform the server it has 5 seconds to finish
        // the request it is currently handling
        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()
    
        // Shutdown server
        log.Println("Shutting down server...")
        if err := srv.Shutdown(ctx); err != nil {
            log.Fatalf("Server forced to shutdown: %v\n", err)
    }
    
    계정 폴더에서 실행 go run main.go 을 통해 이 점을 테스트할 수 없습니다.

    Docker 설치


    계정 디렉터리에 Dockerfile 를 만듭니다.이 Dockerfile은 단계를 사용합니다.첫 번째 단계,builder, 우리는 모든 의존항을 다운로드하고 설치한 다음에 응용 프로그램의 바이너리 파일을 구축합니다.잠시 후,dockercompose 개발 환경에서 이builder 단계를 사용하여 프로그램을 자동으로 다시 불러옵니다.우리는 Reflect라는 프로그램을 통해 이 점을 실현할 것이다. 우리는 구축기 단계에서 이 프로그램을 다운로드할 것이다.
    Dockerfile의 후반부에서builder에서 구축된 프로그램을 추출하여 단독 용기에서 실행합니다.이것은builder 단계에서 모든 불필요한 코드를 제거하고 더욱 간소화된 최종 응용 프로그램 용기를 만들어 배치할 수 있습니다.
    FROM golang:alpine as builder
    
    WORKDIR /go/src/app
    
    # Get Reflex for live reload in dev
    ENV GO111MODULE=on
    RUN go get github.com/cespare/reflex
    
    COPY go.mod .
    COPY go.sum .
    
    RUN go mod download
    
    COPY . .
    
    RUN go build -o ./run .
    
    FROM alpine:latest
    RUN apk --no-cache add ca-certificates
    WORKDIR /root/
    
    #Copy executable from builder
    COPY --from=builder /go/src/app/run .
    
    EXPOSE 8080
    CMD ["./run"]
    

    docker 작성 파일 만들기


    현재, 우리는 dockercompose를 만들 것입니다.yml 파일.이 파일과 같은 폴더에서 명령 docker-compose up 을 실행하기만 하면 이 파일로 여러 개의 docker 용기를 시작하여 개발할 수 있습니다. (기본적으로 명령줄 파라미터도 파일 경로를 정의하는 데 사용할 수 있습니다.)우리는 이 파일을 프로젝트의 루트 폴더에 저장할 것이다.
    이 파일에서 우리는 두 개의 서비스를 만들었다.

  • 리버스 에이전트 -
  • 이 서비스는 Traefik docker 렌즈를 실행합니다. 우리는 역방향 에이전트를 사용하여 http 요청 루트를 우리가 만들 4개의 응용 프로그램에 연결할 것입니다.
  • 명령행 매개변수에 해당하는 명령 배열을 사용하여 Traefik을 구성합니다.이 과정의 경우 TLS 인증서를 설정하지 않으므로 설정--api.insecure=true합니다.다음 두 개의 매개 변수는 Traefik이 docker 용기에서 설정을 찾는 것을 알려 줍니다.그러나 일반적으로 Traefik은 일부 기본값이 있는 Docker 컨테이너를 자동으로 공개합니다.이 기능은 설정 --providers.docker.exposedByDefault=false 을 통해 비활성화됩니다.
  • 이 서비스의 포트 맵 설정은 docker 호스트 (우리의 기계) 에서 표준 http 포트 (80) 에 접근할 수 있도록 하고, Traefik가 포트 8080에서 제공하는 예쁜 계기판에 접근할 수 있도록 합니다.

  • 계정 폴더의 계정 Go 응용 프로그램
  • 우선 이 파일의build 키를 주의하십시오.dockercompose에 계정 폴더에서 찾을 용기를 만들어야 한다고 알려 줍니다.그러나docker 파일이 어떻게'다단계'로 구축되었는지 기억하십니까?개발에 대해 우리는 최종적인 효율적인 구축을 실행할 필요가 없다.따라서 dockercompose는 Dockerfile에서builder로 표시된 첫 번째 구축 단계에서만 용기를 만들 수 있도록 설정합니다.
  • Traefik에서 자동으로 감지하도록 Docker 컨테이너를 설정하는 방법입니다.기본적으로 모든 용기가 공개되지 않기 때문에 현식 설정target: builder이 필요합니다.다음 라벨도 중요합니다.이것은 루트 규칙을 설정하여 Traefik이 http 요청 루트를 "traefik.enable=true" 우리 계정 응용 프로그램에 가져오도록 알려 줍니다.
  • 마지막으로 Dockerfile에 Traefik라는 도구를 설치했습니다.이 도구는 *에 대한 변경 사항을 모니터링합니다.go 파일 (이 예에서 정규 표현식을 사용) 을 사용한 다음main을 다시 실행합니다.파일로 이동합니다.우리는 실제로 malcorp.test/api/account 가 아니라 go run ./ 를 사용합니다. 왜냐하면 우리는 여러 개의 * 를 가지고 있기 때문입니다.루트 디렉토리의 파일로 이동합니다.
  • version: "3.8"
    services:
      reverse-proxy:
        # The official v2 Traefik docker image
        image: traefik:v2.2
        # Enables the web UI and tells Traefik to listen to docker
        command:
          - "--api.insecure=true"
          - "--providers.docker"
          - "--providers.docker.exposedByDefault=false"
        ports:
          # The HTTP port
          - "80:80"
          # The Web UI (enabled by --api.insecure=true)
          - "8080:8080"
        volumes:
          # So that Traefik can listen to the Docker events
          - /var/run/docker.sock:/var/run/docker.sock
      account:
        build:
          context: ./account
          target: builder
        image: account
        expose:
          - "8080"
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.account.rule=Host(`malcorp.test`) && PathPrefix(`/api/account`)"
        environment:
          - ENV=dev
        volumes:
          - ./account:/go/src/app
        # have to use $$ (double-dollar) so docker doesn't try to substitute a variable
        command: reflex -r "\.go$$" -s -- sh -c "go run ./"
    

    반사 동작 호스트 파일에 테스트 도메인 추가


    malcorp를 사용하기 위해서테스트 영역을 개발하기 위해서, 브라우저,curl,postman 등에 입력할 때, 로컬 컴퓨터로 해석될 수 있도록 호스트 파일에 추가해야 합니다.Mac/Linux 또는 c:\windows\system32\drivers\etc\hosts의/etc/hosts에 다음 줄을 추가하면 이 두 줄을 동시에 추가할 수 있습니다.어떤 경우에도 파일을 관리 권한으로 저장해야 합니다(Mac/Linux의 sudo).
    127.0.0.1       malcorp.test
    

    응용 프로그램 실행🤞🏼


    Welp...여기는 아무것도 없어!한번 해볼게요.루트 폴더에서 실행go run main.go(용기를 다시 생성해야 하는 경우 실행docker-compose up)
    이제 브라우저를 열고 입력 docker-compose up --build 하면 JSON 응답을 받을 수 있습니다
    {"hello":"space peoples"}
    
    main의 응답을 변경하려고 시도합니다.가다서버가 다시 시작되고 브라우저를 새로 고치며 새로운 응답을 볼 수 있어야 합니다.

    결론


    워자!그건 정말 너무 많아!
    다음에 우리는 gin 공유기에 루트를 추가하고 계정 응용 프로그램 구조의 세부 사항을 소개할 것입니다.
    "하스타라프로시마!

    좋은 웹페이지 즐겨찾기