도커 배포

20376 단어 godocker
우리 서버는 완성되었고 Docker를 사용하여 수행될 배포 준비가 거의 완료되었습니다. 거의 준비가 되었다고 말씀드렸으니 무엇이 누락되었는지 살펴보겠습니다. 그동안 우리는 포트 3000에서 수신 대기하고 포트 8080에서 모든 요청을 백엔드로 리디렉션하는 React 개발 서버를 사용했습니다. 이는 프런트엔드와 백엔드를 동시에 개발하고 프런트엔드 디버깅을 더 쉽게 만들어주기 때문에 개발에 적합합니다. 리액트 앱. 그러나 프로덕션에서는 필요하지 않으며 백엔드 서버만 실행하고 정적 프런트엔드 파일을 클라이언트에 제공하는 것이 훨씬 더 합리적입니다. 따라서 npm start 명령을 사용하여 React 개발 서버를 시작하는 대신 npm run build 디렉토리 내부의 명령assets/을 사용하여 프로덕션에 최적화된 프런트엔드 파일을 빌드합니다. 그러면 프로덕션에 필요한 모든 파일과 함께 새 디렉토리assets/build/가 생성됩니다. 이제 우리는 또한 이러한 파일을 제공할 수 있는 파일을 찾을 위치를 백엔드에 지시해야 합니다. 명령router.Use(static.Serve("/", static.LocalFile("./assets/build", true)))을 사용하면 됩니다. 물론 서버가 prod 환경에서 시작된 경우에만 그렇게 하려고 하므로 약간의 파일 업데이트가 필요합니다.

먼저 환경 값을 문자열로 반환하도록 Parse()internal/cli/cli.go 함수를 업데이트합니다.

func Parse() string {
  flag.Usage = usage
  env := flag.String("env", "dev", `Sets run environment. Possible values are "dev" and "prod"`)
  flag.Parse()
  logging.ConfigureLogger(*env)
  if *env == "prod" {
    logging.SetGinLogToFile()
  }
  return *env
}


그런 다음 환경 값을 수신하고 설정할 수 있도록 Config structNewConfig() 함수를 업데이트합니다.

type Config struct {
  Host       string
  Port       string
  DbHost     string
  DbPort     string
  DbName     string
  DbUser     string
  DbPassword string
  JwtSecret  string
  Env        string
}

func NewConfig(env string) Config {
  ...
  return Config{
    Host:       host,
    Port:       port,
    DbHost:     dbHost,
    DbPort:     dbPort,
    DbName:     dbName,
    DbUser:     dbUser,
    DbPassword: dbPassword,
    JwtSecret:  jwtSecret,
    Env:        env,
  }
}


이제 CLI에서 env 값을 수신하도록 업데이트internal/cli/main.go하고 서버 시작에 사용할 새 구성 생성으로 보낼 수 있습니다.

func main() {
  env := cli.Parse()
  server.Start(conf.NewConfig(env))
}


다음으로 해야 할 일은 구성 인수를 수신할 수 있도록 라우터를 업데이트하고 프로덕션 모드에서 시작된 경우 정적 파일을 제공하도록 설정하는 것입니다.

package server

import (
  "net/http"
  "rgb/internal/conf"
  "rgb/internal/store"

  "github.com/gin-contrib/static"
  "github.com/gin-gonic/gin"
)

func setRouter(cfg conf.Config) *gin.Engine {
  // Creates default gin router with Logger and Recovery middleware already attached
  router := gin.Default()

  // Enables automatic redirection if the current route can't be matched but a
  // handler for the path with (without) the trailing slash exists.
  router.RedirectTrailingSlash = true

  // Serve static files to frontend if server is started in production environment
  if cfg.Env == "prod" {
    router.Use(static.Serve("/", static.LocalFile("./assets/build", true)))
  }

  // Create API route group
  api := router.Group("/api")
  api.Use(customErrors)
  {
    api.POST("/signup", gin.Bind(store.User{}), signUp)
    api.POST("/signin", gin.Bind(store.User{}), signIn)
  }

  authorized := api.Group("/")
  authorized.Use(authorization)
  {
    authorized.GET("/posts", indexPosts)
    authorized.POST("/posts", gin.Bind(store.Post{}), createPost)
    authorized.PUT("/posts", gin.Bind(store.Post{}), updatePost)
    authorized.DELETE("/posts/:id", deletePost)
  }

  router.NoRoute(func(ctx *gin.Context) { ctx.JSON(http.StatusNotFound, gin.H{}) })

  return router
}


업데이트가 필요한 마지막 줄은 migrations/main.go 파일에 있습니다. 그냥 변경

store.SetDBConnection(database.NewDBOptions(conf.NewConfig()))


에게

store.SetDBConnection(database.NewDBOptions(conf.NewConfig("dev")))


사실 그게 마지막이 아니다. 또한 구성 및 라우터 설정을 사용하는 모든 테스트를 업데이트해야 하지만 이는 전적으로 사용자에게 달려 있으며 구현한 테스트에 따라 다릅니다.

이제 Docker 배포를 위한 모든 준비가 완료되었습니다. Docker는 이 가이드의 범위에 포함되지 않으므로 Dockerfile, .dockerignore and docker-compose.yml 콘텐츠에 대한 자세한 내용은 다루지 않겠습니다.

먼저 프로젝트 루트 디렉토리에 .dockerignore 파일을 생성합니다.

# This file
.dockerignore

# Git files
.git/
.gitignore

# VS Code config dir
.vscode/

# Docker configuration files
docker/

# Assets dependencies and built files
assets/build/
assets/node_modules/

# Log files
logs/

# Built binary
cmd/rgb/rgb

# ENV file
.env

# Readme file
README.md


이제 docker/ 두 개의 파일로 새 디렉토리Dockerfile and docker-compose.yml를 만듭니다. Dockerfile의 내용은 다음과 같습니다.

FROM node:16 AS frontendBuilder

# set app work dir
WORKDIR /rgb

# copy assets files to the container
COPY assets/ .

# set assets/ as work dir to build frontend static files
WORKDIR /rgb/assets
RUN npm install
RUN npm run build

FROM golang:1.16.3 AS backendBuilder

# set app work dir
WORKDIR /go/src/rgb

# copy all files to the container
COPY . .

# build app executable
RUN CGO_ENABLED=0 GOOS=linux go build -o cmd/rgb/rgb cmd/rgb/main.go

# build migrations executable
RUN CGO_ENABLED=0 GOOS=linux go build -o migrations/migrations migrations/*.go

FROM alpine:3.14

# Create a group and user deploy
RUN addgroup -S deploy && adduser -S deploy -G deploy

ARG ROOT_DIR=/home/deploy/rgb

WORKDIR ${ROOT_DIR}

RUN chown deploy:deploy ${ROOT_DIR}

# copy static assets file from frontend build
COPY --from=frontendBuilder --chown=deploy:deploy /rgb/build ./assets/build

# copy app and migrations executables from backend builder
COPY --from=backendBuilder --chown=deploy:deploy /go/src/rgb/migrations/migrations ./migrations/
COPY --from=backendBuilder --chown=deploy:deploy /go/src/rgb/cmd/rgb/rgb .

# set user deploy as current user
USER deploy

# start app
CMD [ "./rgb", "-env", "prod" ]

docker-compose.yml의 내용은 다음과 같습니다.

version: "3"
services:
  rgb:
    image: kramat/rgb
    env_file:
      - ../.env
    environment:
      RGB_DB_HOST: db
    depends_on:
      - db
    ports:
      - ${RGB_PORT}:${RGB_PORT}
  db:
    image: postgres
    environment:
      POSTGRES_USER: ${RGB_DB_USER}
      POSTGRES_PASSWORD: ${RGB_DB_PASSWORD}
      POSTGRES_DB: ${RGB_DB_NAME}
    ports:
      - ${RGB_DB_PORT}:${RGB_DB_PORT}
    volumes:
      - postgresql:/var/lib/postgresql/rgb
      - postgresql_data:/var/lib/postgresql/rgb/data
volumes:
  postgresql: {}
  postgresql_data: {}


이제 Docker 배포에 필요한 모든 파일이 준비되었으므로 Docker 이미지를 빌드하고 배포하는 방법을 살펴보겠습니다. 먼저 공식 Docker 컨테이너 저장소에서 이미지postgres를 가져옵니다.

docker pull postgres


다음 단계는 rgb 이미지를 빌드하는 것입니다. 프로젝트 루트 디렉토리 내부 실행(자체 도커 ID로 변경DOCKER_ID):

docker build -t DOCKER_ID/rgb -f docker/Dockerfile .


리소스가 있는 rgbdb 컨테이너를 생성하려면 다음을 실행합니다.

cd docker/
docker-compose up -d


그러면 두 컨테이너가 모두 시작되며 docker ps 를 실행하여 상태를 확인할 수 있습니다. 마지막으로 마이그레이션을 실행해야 합니다. 다음을 실행하여 rgb 컨테이너에서 셸을 엽니다.

docker-compose run --rm rgb sh


컨테이너 내부에서 이전과 동일하게 마이그레이션을 실행할 수 있습니다.

cd migrations/
./migrations init
./migrations up


그리고 끝났습니다. 브라우저에서 localhost:8080를 열어 모든 것이 제대로 작동하는지 확인할 수 있습니다. 즉, 계정을 만들고 새 게시물을 추가할 수 있어야 합니다.



간단한 웹앱 치고는 꽤 길었지만 이 가이드를 완성했습니다. 여러분 중 일부에게 도움이 되었기를 바랍니다. 질문이나 의견이 있거나 문제를 발견한 경우 언제든지 의견을 보내주십시오. 모두에게 행운과 행복한 코딩 :)

좋은 웹페이지 즐겨찾기