도커 배포
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 .
리소스가 있는
rgb
및 db
컨테이너를 생성하려면 다음을 실행합니다.cd docker/
docker-compose up -d
그러면 두 컨테이너가 모두 시작되며
docker ps
를 실행하여 상태를 확인할 수 있습니다. 마지막으로 마이그레이션을 실행해야 합니다. 다음을 실행하여 rgb
컨테이너에서 셸을 엽니다.docker-compose run --rm rgb sh
컨테이너 내부에서 이전과 동일하게 마이그레이션을 실행할 수 있습니다.
cd migrations/
./migrations init
./migrations up
그리고 끝났습니다. 브라우저에서
localhost:8080
를 열어 모든 것이 제대로 작동하는지 확인할 수 있습니다. 즉, 계정을 만들고 새 게시물을 추가할 수 있어야 합니다.간단한 웹앱 치고는 꽤 길었지만 이 가이드를 완성했습니다. 여러분 중 일부에게 도움이 되었기를 바랍니다. 질문이나 의견이 있거나 문제를 발견한 경우 언제든지 의견을 보내주십시오. 모두에게 행운과 행복한 코딩 :)
Reference
이 문제에 관하여(도커 배포), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/matijakrajnik/docker-deploy-1aa7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)