From 16d25f034ed745394e8c07bbc6cdb14d092875de Mon Sep 17 00:00:00 2001 From: nyne Date: Thu, 15 May 2025 16:21:20 +0800 Subject: [PATCH] Add Docker support. --- Dockerfile | 47 +++++++++++++++++++++++++++++++++ docker-compose.yml | 36 +++++++++++++++++++++++++ frontend/src/network/network.ts | 14 ++++++++++ go.mod | 7 ++++- go.sum | 9 +++++++ main.go | 7 +++-- server/dao/db.go | 27 ++++++++++++++++--- 7 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b4506f8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ + +# 第一阶段:构建前端 +FROM node:22-alpine AS frontend-builder + +WORKDIR /app/frontend + +# 复制前端项目文件 +COPY frontend/package*.json ./ +RUN npm install + +COPY frontend/ ./ +RUN npm run build + +# 第二阶段:构建Go应用 +FROM golang:1.24-alpine AS backend-builder + +WORKDIR /app + +# 安装GCC和相关构建工具 +RUN apk add --no-cache gcc musl-dev + +# 复制Go项目文件 +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +# 构建Go应用 +RUN CGO_ENABLED=1 GOOS=linux go build -o main . + +# 第三阶段:最终运行镜像 +FROM alpine:latest + +WORKDIR /app + +# 安装必要的运行时依赖 +RUN apk --no-cache add ca-certificates tzdata + +# 从后端构建阶段复制构建产物 +COPY --from=backend-builder /app/main /app/ +COPY --from=frontend-builder /app/frontend/dist /app/static + +# 暴露应用端口(根据您的应用实际端口调整) +EXPOSE 3000 + +# 运行应用 +CMD ["./main"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..aae424c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,36 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "3000:3000" + volumes: + - app_data:/var/lib/nysoure + depends_on: + - db + environment: + - DB_HOST=db + - DB_PORT=3306 + - DB_USER=nysoure + - DB_PASSWORD=nysoure_password + - DB_NAME=nysoure + - DEBUG_MODE=false + restart: unless-stopped + + db: + image: mariadb:latest + volumes: + - db_data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=root_password + - MYSQL_DATABASE=nysoure + - MYSQL_USER=nysoure + - MYSQL_PASSWORD=nysoure_password + ports: + - "3306" + restart: unless-stopped + +volumes: + app_data: + db_data: diff --git a/frontend/src/network/network.ts b/frontend/src/network/network.ts index 7e9fe82..89c45cf 100644 --- a/frontend/src/network/network.ts +++ b/frontend/src/network/network.ts @@ -27,6 +27,7 @@ class Network { } init() { + this.testToken() if (import.meta.env.MODE === 'development') { this.baseUrl = 'http://localhost:3000'; this.apiBaseUrl = 'http://localhost:3000/api'; @@ -58,6 +59,19 @@ class Network { }) } + async testToken(): Promise { + if (!app.token) { + return; + } + const res = await this.getUserInfo(app.user!.username) + if (!res.success) { + app.token = null; + app.user = null; + app.saveData(); + window.location.reload(); + } + } + async login(username: string, password: string): Promise> { try { const response = await axios.postForm(`${this.apiBaseUrl}/user/login`, { diff --git a/go.mod b/go.mod index d149ee6..3b3768e 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,12 @@ require ( gorm.io/gorm v1.26.1 ) -require github.com/chai2010/webp v1.4.0 +require ( + github.com/chai2010/webp v1.4.0 + gorm.io/driver/mysql v1.5.7 +) + +require github.com/go-sql-driver/mysql v1.7.0 // indirect require ( github.com/dustin/go-humanize v1.0.1 // indirect diff --git a/go.sum b/go.sum index 9d05595..c38de86 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vt github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0= @@ -24,11 +26,13 @@ github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b h1:EY/KpStFl60 github.com/gomarkdown/markdown v0.0.0-20250311123330-531bef5e742b/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/k3a/html2text v1.2.1 h1:nvnKgBvBR/myqrwfLuiqecUtaK1lB9hGziIJKatNFVY= github.com/k3a/html2text v1.2.1/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIBmgUqA= @@ -55,7 +59,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -87,7 +93,10 @@ golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= +gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I= gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.26.1 h1:ghB2gUI9FkS46luZtn6DLZ0f6ooBJ5IbVej2ENFDjRw= gorm.io/gorm v1.26.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= diff --git a/main.go b/main.go index 6ce29df..6450cf9 100644 --- a/main.go +++ b/main.go @@ -4,17 +4,16 @@ import ( "log" "nysoure/server/api" "nysoure/server/middleware" + "os" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/cors" "github.com/gofiber/fiber/v3/middleware/logger" ) -const ( - debugMode = true -) - func main() { + debugMode := os.Getenv("DEBUG_MODE") != "false" + app := fiber.New(fiber.Config{ BodyLimit: 8 * 1024 * 1024, TrustProxy: true, diff --git a/server/dao/db.go b/server/dao/db.go index 7aee6f6..f24cfe7 100644 --- a/server/dao/db.go +++ b/server/dao/db.go @@ -1,18 +1,37 @@ package dao import ( + "gorm.io/driver/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" "nysoure/server/model" + "os" + "time" ) var db *gorm.DB func init() { - var err error - db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) - if err != nil { - panic("failed to connect database") + if os.Getenv("DB_PORT") != "" { + host := os.Getenv("DB_HOST") + port := os.Getenv("DB_PORT") + user := os.Getenv("DB_USER") + password := os.Getenv("DB_PASSWORD") + dbName := os.Getenv("DB_NAME") + dsn := user + ":" + password + "@tcp(" + host + ":" + port + ")/" + dbName + "?charset=utf8mb4&parseTime=True&loc=Local" + var err error + // wait for mysql to be ready + time.Sleep(5 * time.Second) + db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) + if err != nil { + panic("failed to connect database") + } + } else { + var err error + db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + if err != nil { + panic("failed to connect database") + } } _ = db.AutoMigrate(&model.User{}, &model.Resource{}, &model.Image{}, &model.Tag{}, &model.Storage{}, &model.File{}, &model.UploadingFile{}, &model.Statistic{}, &model.Comment{})