You've already forked orderservice
feat: added migrations
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
ARG GOARCH=amd64
|
||||||
|
ARG GOOS=linux
|
||||||
|
ARG CGO_ENABLED=0
|
||||||
|
ARG VERSION=1.0.0
|
||||||
|
ARG BUILD_TIME=unknown
|
||||||
|
|
||||||
|
# Stage 1: Build
|
||||||
|
FROM docker.io/golang:1.24-alpine AS build
|
||||||
|
|
||||||
|
ARG GOOS
|
||||||
|
ARG GOARCH
|
||||||
|
ARG CGO_ENABLED
|
||||||
|
ARG VERSION
|
||||||
|
ARG BUILD_TIME
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=${CGO_ENABLED} \
|
||||||
|
GOOS=${GOOS} \
|
||||||
|
GOARCH=${GOARCH} \
|
||||||
|
go build -trimpath \
|
||||||
|
-ldflags="-s -w -X 'main.Version=${VERSION}' -X 'main.BuildTime=${BUILD_TIME}'" \
|
||||||
|
-o /bin/app ./cmd/migrate
|
||||||
|
|
||||||
|
# Stage 2: Runtime
|
||||||
|
FROM docker.io/alpine:3.22 AS runtime
|
||||||
|
|
||||||
|
ARG VERSION
|
||||||
|
ARG BUILD_TIME
|
||||||
|
|
||||||
|
RUN addgroup -S app && adduser -S -G app app
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=build /bin/app /app/bin
|
||||||
|
|
||||||
|
RUN chown app:app /app/bin && chmod +x /app/bin
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.version=${VERSION}
|
||||||
|
LABEL org.opencontainers.image.created=${BUILD_TIME}
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/bin"]
|
||||||
|
|
||||||
|
CMD [""]
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
# Go parameters
|
# Go parameters
|
||||||
GOCMD=go
|
GOCMD=go
|
||||||
GOBUILD=$(GOCMD) build
|
GOBUILD=$(GOCMD) build -trimpath -ldflags="-s -w"
|
||||||
GOTEST=$(GOCMD) test
|
GOTEST=$(GOCMD) test
|
||||||
GODOWNLOAD=$(GOCMD) mod download
|
GODOWNLOAD=$(GOCMD) mod download
|
||||||
BINARY_NAME=orderservice
|
BINARY_NAME=orderservice
|
||||||
|
MIGRATE_BINARY_NAME=orderservice-migrate
|
||||||
BINARY_DIR=bin
|
BINARY_DIR=bin
|
||||||
|
|
||||||
# Protobuf parameters
|
# Protobuf parameters
|
||||||
@@ -12,7 +13,7 @@ PROTO_DIR=api/proto
|
|||||||
PROTO_FILE=$(PROTO_DIR)/order.proto
|
PROTO_FILE=$(PROTO_DIR)/order.proto
|
||||||
PROTO_OUT=.
|
PROTO_OUT=.
|
||||||
|
|
||||||
.PHONY: install i generate gen protoc test build run lint fmt format clean help
|
.PHONY: install i generate gen generate-gw test build run migrate lint fmt format clean help
|
||||||
|
|
||||||
install:
|
install:
|
||||||
$(GODOWNLOAD)
|
$(GODOWNLOAD)
|
||||||
@@ -38,9 +39,21 @@ build:
|
|||||||
$(GOBUILD) -o ./$(BINARY_DIR)/$(BINARY_NAME) ./cmd/server
|
$(GOBUILD) -o ./$(BINARY_DIR)/$(BINARY_NAME) ./cmd/server
|
||||||
chmod +x ./$(BINARY_DIR)/$(BINARY_NAME)
|
chmod +x ./$(BINARY_DIR)/$(BINARY_NAME)
|
||||||
|
|
||||||
|
build-migrate:
|
||||||
|
$(GOBUILD) -o ./$(BINARY_DIR)/$(MIGRATE_BINARY_NAME) ./cmd/migrate
|
||||||
|
chmod +x ./$(BINARY_DIR)/$(MIGRATE_BINARY_NAME)
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
./$(BINARY_DIR)/$(BINARY_NAME)
|
./$(BINARY_DIR)/$(BINARY_NAME)
|
||||||
|
|
||||||
|
migrate: build-migrate
|
||||||
|
@cmd=$(word 2,$(MAKECMDGOALS)); \
|
||||||
|
if [ -z "$$cmd" ]; then \
|
||||||
|
echo "Usage: make migrate <command>"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
./$(BINARY_DIR)/$(MIGRATE_BINARY_NAME) -cmd $$cmd
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run -c .golangci.yaml ./...
|
golangci-lint run -c .golangci.yaml ./...
|
||||||
|
|
||||||
@@ -68,3 +81,6 @@ help:
|
|||||||
@echo " clean - Clean build artifacts"
|
@echo " clean - Clean build artifacts"
|
||||||
|
|
||||||
.DEFAULT_GOAL := help
|
.DEFAULT_GOAL := help
|
||||||
|
|
||||||
|
%:
|
||||||
|
@:
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"embed"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"orderservice/internal/config"
|
||||||
|
|
||||||
|
"github.com/golang-migrate/migrate/v4"
|
||||||
|
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||||
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed migrations/*.sql
|
||||||
|
var migrationsFS embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var cmd string
|
||||||
|
|
||||||
|
flag.StringVar(&cmd, "cmd", "up", "migration command: up|down|force|version")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
cfg, err := config.Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to load config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := sql.Open("postgres", cfg.BuildPostgresDSN())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("open db: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
drv, err := postgres.WithInstance(db, &postgres.Config{})
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("postgres driver: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
src, err := iofs.New(migrationsFS, "migrations")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("iofs source: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := migrate.NewWithInstance("iofs", src, "postgres", drv)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("migrate NewWithInstance: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cmd {
|
||||||
|
case "up":
|
||||||
|
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
||||||
|
log.Printf("m.Up failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("migrations applied (up)")
|
||||||
|
case "down":
|
||||||
|
if err := m.Steps(-1); err != nil {
|
||||||
|
log.Printf("m.Steps(-1) failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("stepped down 1 migration")
|
||||||
|
case "version":
|
||||||
|
v, dirty, verr := m.Version()
|
||||||
|
if verr != nil {
|
||||||
|
log.Printf("version: %v", verr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("version: %d dirty: %v\n", v, dirty)
|
||||||
|
default:
|
||||||
|
log.Printf("unknown cmd: %s", cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
drop table if exists orders;
|
||||||
@@ -6,6 +6,10 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Containerfile
|
dockerfile: Containerfile
|
||||||
depends_on:
|
depends_on:
|
||||||
|
migrate:
|
||||||
|
restart: false
|
||||||
|
condition: service_completed_successfully
|
||||||
|
required: true
|
||||||
postgres:
|
postgres:
|
||||||
restart: false
|
restart: false
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -36,6 +40,24 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
shm_size: 4mb
|
shm_size: 4mb
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Containerfile.migrate
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
restart: false
|
||||||
|
condition: service_healthy
|
||||||
|
required: true
|
||||||
|
env_file:
|
||||||
|
- path: ./infrastructure/core/.env.template
|
||||||
|
required: true
|
||||||
|
- path: ./infrastructure/core/.env
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
restart: no
|
||||||
|
shm_size: 4mb
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
image: docker.io/postgres:17-alpine
|
image: docker.io/postgres:17-alpine
|
||||||
configs:
|
configs:
|
||||||
|
|||||||
Reference in New Issue
Block a user