Skip to content

Commit

Permalink
도커파일 버전 최신으로 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
myeunee committed Nov 3, 2024
1 parent a550bcf commit a59d31e
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 3 deletions.
2 changes: 1 addition & 1 deletion chapter15/section57/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Build stage
# 최신 버전으로 수정 ******
FROM golang:1.22-bullseye as deploy-builder
FROM golang:1.23.1 AS deploy-builder

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion chapter16/section60/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Build stage
# 최신 버전으로 수정 ******
FROM golang:1.22-bullseye as deploy-builder
FROM golang:1.23.1 AS deploy-builder

WORKDIR /app

Expand Down
2 changes: 1 addition & 1 deletion chapter16/section60/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

DOCKER_TAG := latest
build: ## 배포용 도커 이미지 빌드 + 내 모듈 이름에 맞게 수정 **********
docker build -t myeunee/golangstudy-chapter15-section57:${DOCKER_TAG} --target deploy ./
docker build -t myeunee/golangstudy-chapter16-section60:${DOCKER_TAG} --target deploy ./

build-local: ## 로컬 환경용 도커 이미지 빌드
docker compose build --no-cache
Expand Down
2 changes: 2 additions & 0 deletions chapter16/section61/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
.DS_Store
35 changes: 35 additions & 0 deletions chapter16/section61/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Build stage
# 최신 버전으로 수정 ******
FROM golang:1.23.1 AS deploy-builder

WORKDIR /app

# go.mod, go.sum 파일 복사 및 의존성 다운로드
COPY go.mod go.sum ./
RUN go mod download

COPY . .
# 바이너리 빌드
RUN go build -trimpath -ldflags "-w -s" -o app

#--------------------------------
# Deployment stage

FROM debian:bullseye-slim as deploy

RUN apt-get update

# 빌드된 바이너리를 복사
COPY --from=deploy-builder /app/app .

# 실행 명령
CMD ["./app"]

#--------------------------------
# Development stage with Air for live reloading

# ******** 최신 버전으로 수정 ***********
FROM golang:1.23.1 as dev
WORKDIR /app
RUN go install github.com/air-verse/air@latest
CMD ["air"]
28 changes: 28 additions & 0 deletions chapter16/section61/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.PHONY: help build build-local up down logs ps test
.DEFAULT_GOAL := help

DOCKER_TAG := latest
build: ## 배포용 도커 이미지 빌드 + 내 모듈 이름에 맞게 수정 **********
docker build -t myeunee/golangstudy-chapter16-section61:${DOCKER_TAG} --target deploy ./

build-local: ## 로컬 환경용 도커 이미지 빌드
docker compose build --no-cache

up: ## 자동 새로고침을 사용한 도커 컴포즈 실행
docker compose up -d

down: ## 도커 컴포즈 종료
docker compose down

logs: ## 도커 컴포즈 로그 출력
docker compose logs -f

ps: ## 컨테이너 상태 확인
docker compose ps

test: ## 테스트 실행
go test -race -shuffle=on ./...

help: ## 옵션 보기
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
33 changes: 33 additions & 0 deletions chapter16/section61/air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
root = "."
tmp_dir = "tmp"

[build]
cmd = "go build -o ./tmp/main ."
# 'cmd'에서 바이너리 파일 지정
bin = "tmp/main"

# 80번 포트를 사용하도록 실행 시 인수를 지정
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main 80"

include_ext = ["go", "tpl", "tmpl", "html"]
exclude_dir = ["assets", "tmp", "vendor"]
exclude_regex = ["_test.go"]
exclude_unchanged = true
follow_symlink = true
log = "air.log"
delay = 1000
stop_on_error = true
send_interrupt = false
kill_delay = 500

[log]
time = false

[color]
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
clean_on_exit = true
18 changes: 18 additions & 0 deletions chapter16/section61/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package config

import (
"github.com/caarlos0/env/v6"
)

type Config struct {
Env string `env:"TODO_ENV" envDefault:"dev"`
Port int `env:"PORT" envDefault:"80"`
}

func New() (*Config, error) {
cfg := &Config{}
if err := env.Parse(cfg); err != nil {
return nil, err
}
return cfg, nil
}
23 changes: 23 additions & 0 deletions chapter16/section61/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package config

import (
"fmt"
"testing"
)

func TestNew(t *testing.T) {
wantPort := 3333
t.Setenv("PORT", fmt.Sprint(wantPort))

got, err := New()
if err != nil {
t.Fatalf("cannot create config: %v", err)
}
if got.Port != wantPort {
t.Errorf("want %d, but %d", wantPort, got.Port)
}
wantEnv := "dev"
if got.Env != wantEnv {
t.Errorf("want %s, but %s", wantEnv, got.Env)
}
}
14 changes: 14 additions & 0 deletions chapter16/section61/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: "3.9"
services:
app:
image: gotodo
build:
args:
- target=dev
environment:
TODO_ENV: dev
PORT: 8080
volumes:
- .:/app
ports:
- "18000:8080"
8 changes: 8 additions & 0 deletions chapter16/section61/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/myeunee/GolangStudy/chapter16/section61

go 1.23.1

require (
github.com/caarlos0/env/v6 v6.10.1
golang.org/x/sync v0.8.0
)
4 changes: 4 additions & 0 deletions chapter16/section61/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
68 changes: 68 additions & 0 deletions chapter16/section61/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package main

import (
"context"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"github.com/myeunee/GolangStudy/chapter16/section61/config"
"golang.org/x/sync/errgroup"
)

// run 함수만 호출하도록
func main() {
if err := run(context.Background()); err != nil {
log.Printf("failed to terminated server: %v", err)
os.Exit(1)
}
}

func run(ctx context.Context) error {
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
defer stop()
cfg, err := config.New()
if err != nil {
return err
}
l, err := net.Listen("tcp", fmt.Sprintf(":%d", cfg.Port))
if err != nil {
log.Fatalf("failed to listen port %d: %v", cfg.Port, err)
}
url := fmt.Sprintf("http://%s", l.Addr().String())
log.Printf("start with: %v", url)
s := &http.Server{
// 인수로 받은 net.Listener를 이용 -> Addr 필드 지정 X
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 명령줄에서 테스트하기 위한 로직
time.Sleep(5 * time.Second)
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}),
}
eg, ctx := errgroup.WithContext(ctx)
// 다른 고루틴에서 http 서버 실행
eg.Go(func() error {
// ListenAndServe 가 아니라 Serve 메서드로 변경
if err := s.Serve(l); err != nil &&
// http.ErrServerClosed는
// http.Server.Shutdown()가 정상 종료되었다고 표시하므로 문제 X。
err != http.ErrServerClosed {
log.Printf("failed to close: %+v", err)
return err
}
return nil
})

// 채널로부터 알림(종료 알림)을 기다림
<-ctx.Done()
if err := s.Shutdown(context.Background()); err != nil {
log.Printf("failed to shutdown: %+v", err)
}
// Go메서드로 실행한 다른 고루틴의 종료를 기다림
return eg.Wait()
}
50 changes: 50 additions & 0 deletions chapter16/section61/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"context"
"fmt"
"io"
"net"
"net/http"
"testing"

"golang.org/x/sync/errgroup"
)

func TestRun(t *testing.T) {
t.Skip("리팩토링 중")

l, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("failed to listen port %v", err)
}
ctx, cancel := context.WithCancel(context.Background())
eg, ctx := errgroup.WithContext(ctx)
eg.Go(func() error {
return run(ctx)
})
in := "message"
url := fmt.Sprintf("http://%s/%s", l.Addr().String(), in)
// // 어떤 포트로 리슨하고 있는지 확인
t.Logf("try request to %q", url)
rsp, err := http.Get(url)
if err != nil {
t.Errorf("failed to get: %+v", err)
}
defer rsp.Body.Close()
got, err := io.ReadAll(rsp.Body)
if err != nil {
t.Fatalf("failed to read body: %v", err)
}
// http 서버의 반환값을 검증
want := fmt.Sprintf("Hello, %s!", in)
if string(got) != want {
t.Errorf("want %q, but got %q", want, got)
}
// run함수에 종료 알림을 전송
cancel()
// run함수의 반환값을 검증
if err := eg.Wait(); err != nil {
t.Fatal(err)
}
}

0 comments on commit a59d31e

Please sign in to comment.