docker gin 시작하기

joojong·2023년 1월 12일
0

1차 개발이 끝나고 후기에서 golang으로 개발하고싶은 욕구가 끌어올라서 golang을 취미로 시작하게 됐다. 취미로 시작했더라도 대충하는 짓은 좋아하지 않기 때문에 예전부터 만들고 싶었던 서비스를 만들 계획이다.

개발환경

도커가 빠질 수는 없다.

프로젝트 폴더에 gin 디렉토리를 생성하고 gin dir안에 Dockerfile을 만든다

gin/Dockerfile

FROM golang:1.19-alpine

ENV PROJECT_DIR=/app \
    GO111MODULE=on \
    CGO_ENABLED=0

WORKDIR /app
RUN mkdir "/build"
COPY . .
RUN go get github.com/githubnemo/CompileDaemon
RUN go install github.com/githubnemo/CompileDaemon
ENTRYPOINT CompileDaemon -build="go build -o /build/app" -command="/build/app"

이미 live reload에 길들여져 있기 때문에 개발할 때에는 CompileDaemon을 사용하여 저장시 서버가 reload되게 만든다.

docker-compose.yml

version: "3"
services:
  gin:
    build:
      context: "./gin"
      dockerfile: Dockerfile
    container_name: gin
    restart: unless-stopped
    ports:
      - 7070:7070
    env_file:
      - ./.env
    volumes:
      - ./gin:/app
      - /tmp/mysqld:/run/mysqld
    depends_on:
      - mysql
  mysql:
    platform: linux/amd64 # m1
    image: "mysql:8.0.21"
    logging:
      driver: none
    restart: always
    container_name: mysql
    ports:
      - "3306:3306"
    env_file:
      - ./.env
    volumes:
      - ./mysql/conf.d:/etc/mysql/conf.d
      - ./mysql/data:/var/lib//mysql #when using stack data in server
      - ./mysql/initdb.d:/docker-entrypoint-initdb.d #when using stack data in server
    cap_add:
      - SYS_NICE
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

mysql도 같이 올려준다.
compose에 대한 설명은 다음에....

gin/main.go

package main

func main() {
	r := routers.InitRouter()
	r.Run(":8090")
}

8090포트로 실행 (8080은 spring이 올라가있었습니다. 마음껏 바꾸세요.)

gin/common/database/connection.go

package database

var DB *gorm.DB

func InitDb() *gorm.DB {
	DB = connection()
	return DB
}

func connection() *gorm.DB {
	var user string
	if os.Getenv("MYSQL_USER") == "" {
		user = "root"
	} else {
		user = os.Getenv("MYSQL_USER")
	}
	uri := fmt.Sprintf(
		"%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=true",
		user,
		os.Getenv("MYSQL_ROOT_PASSWORD"),
		"mysql",
		3306,
		os.Getenv("MYSQL_DATABASE"),
	)
	db, err := gorm.Open(mysql.Open(uri), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		fmt.Println("error:::", err)
		panic(err)
	}
	db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(
		// 생성해둔 model을 마이그레이션 해줌
	)

	return db
}

gorm을 사용해서 connection을 맺어주는데 gorm은 나중에 설명하겠습니다.
common 디렉토리에는 공통을 모두 모아둘 예정인데 그 이유는 나중에 공통은 module로 따로 빼서 git에 올려두고 따로 관리할 예정이기 때문입니다.

gin/routers/health_checker.go

package routers

func HealthCheck(c *gin.Context) {
	db, err := database.DB.DB()
	if err != nil {
		c.JSON(http.StatusBadGateway, gin.H{
			"result": false,
		})
		panic(nil)
	}
	database := db.Stats()
	c.JSON(http.StatusOK, gin.H{
		"result": true,
		"database":   database,
	})
}

health checker

gin/routers/routers.go

package routers

func InitRouter() *gin.Engine {
	r := gin.Default()

	r.GET("/health/check", HealthCheck)

	return r
}

nestjs로 개발할 때도 RouterModule로 router들을 한곳에 모아두고 관리하기 때문에 웬만하면 라우터들은 한곳에 모아두는 것을 선호합니다


이정도만 구성해줘도 golang으로 서버를 개발할 수 있다.

root 에서 docker-compose up --build 를 입력하면 build후 컨테이너가 생성된다

curl -X 'GET' \
  'http://127.0.0.1:8090/health/check' \
  -H 'accept: application/json'

터미널에서 위 커맨드를 입력하면 서버가 제대로 올라왔는지 확인할 수 있다..

일주일정도 golang으로 개발한 후기

확실히 nestjs , fastapi , spring보다 response떨어지는게 빠르다.
개발하고 있는 앱 서버 api server , scheduler , socket가 nestjs로 구성되어 있고 각각 다른 이미지로 빌드되서 올라가는데 registry에 올라가있는 이미지 크기만 440MB정도(docker desktop에 올라가 있는 이미지는 1.9GB 정도 된다...) 나오고 레플리카로 생성되는 pod도 존재하기 때문에 리소스를 꽤나 잡아먹고 있는데 gin으로 빌드한 이미지는 docker desktop에서만 360MB정도 밖에 되지 않는다.. 아직 golang을 시작한지 일주일도 되지 않았지만 개인 프로젝트는 당분간 golang으로 할 거 같다.

profile
Back-end developer

0개의 댓글