重构 Dockerfile 添加构建过程

This commit is contained in:
2025-04-19 15:59:31 +08:00
parent 058c4f4313
commit f51808564c
6 changed files with 130 additions and 191 deletions

View File

@@ -1,10 +1,44 @@
FROM ubuntu:20.04
# 第一阶段:构建
FROM golang:1.24.0 AS builder
WORKDIR /build
# 复制Go模块文件
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码
COPY . .
# 编译
RUN GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o bin/platform_linux_amd64 cmd/main/main.go
# 第二阶段:运行环境
FROM ubuntu:24.04
WORKDIR /app
COPY ./bin/platform_linux_amd64 /app/platform
# 安装依赖包
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 从构建阶段复制编译好的二进制文件
COPY --from=builder /build/bin/platform_linux_amd64 /app/platform
# 设置可执行权限
RUN chmod +x /app/platform
EXPOSE $APP_PORT
# 创建存放密钥文件的目录
RUN mkdir -p /app/certs
CMD ["/app/proxy"]
# 声明暴露端口(实际端口通过环境变量传入)
ENV APP_PORT=8080
EXPOSE ${APP_PORT}
# 声明卷,用于在运行时挂载私密的证书文件
VOLUME ["/app/certs"]
# 启动平台服务
CMD ["/app/platform"]

View File

@@ -1,36 +0,0 @@
Remove-Job *
$tasks = 0
$start = Get-Date
$tasks++
Write-Output "building platform for linux amd64..."
Start-Job -ScriptBlock {
$env:GOOS = "linux"; $env:GOARCH = "amd64"; go build -ldflags '-w -s' -o bin/platform_linux_amd64 cmd/main/main.go
} | Out-Null
$tasks++
Write-Output "building tasks for linux amd64..."
Start-Job -ScriptBlock {
$env:GOOS = "linux"; $env:GOARCH = "amd64"; go build -ldflags '-w -s' -o bin/tasks_linux_amd64 cmd/tasks/main.go
} | Out-Null
# Wait for all jobs to complete
while ($tasks -gt 0)
{
foreach ($job in Get-Job)
{
if ($job.State -eq "Completed")
{
$tasks--
$job | Receive-Job
$job | Remove-Job
}
}
}
$end = Get-Date
Write-Output "build completed"
Write-Output "time taken: $( ($end - $start).TotalSeconds ) seconds"
Write-Output "output files are in ./bin/"

View File

@@ -1,132 +0,0 @@
package main
import (
"context"
"encoding/json"
"errors"
"io"
"log/slog"
"net/http"
"platform/pkg/env"
"platform/pkg/logs"
"platform/pkg/rds"
"strconv"
"strings"
"sync"
"time"
"github.com/redis/go-redis/v9"
)
var RemoveEndpoint = "http://localhost:8080/api/channel/remove"
func main() {
Start()
}
var taskList = make(map[string]func(ctx context.Context, curr time.Time) error)
func Start() {
ctx := context.Background()
env.Init()
logs.Init()
rds.Init()
taskList["stopChannels"] = stopChannels
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
// 互斥锁确保同一时间只有一个协程运行
// 如果之前的 tick 操作未完成,则跳过当前 tick
var mutex = &sync.Mutex{}
for curr := range ticker.C {
if mutex.TryLock() {
err := process(ctx, curr)
if err != nil {
panic(err)
}
mutex.Unlock()
} else {
slog.Warn("skip tick", slog.String("tick", curr.Format("2006-01-02 15:04:05")))
}
}
}
func process(ctx context.Context, curr time.Time) error {
// todo 异步化
for name, task := range taskList {
err := task(ctx, curr)
if err != nil {
slog.Error("task failed", slog.String("task", name), slog.String("error", err.Error()))
}
}
return nil
}
func stopChannels(ctx context.Context, curr time.Time) error {
// 查询过期的 channel
result, err := rds.Client.ZRangeByScore(ctx, "tasks:channel", &redis.ZRangeBy{
Min: "0",
Max: strconv.FormatInt(curr.Unix(), 10),
}).Result()
if err != nil {
return err
}
if len(result) == 0 {
return nil
}
ids := make([]int32, len(result))
for i, str := range result {
id, err := strconv.ParseInt(str, 10, 32)
if err != nil {
return err
}
ids[i] = int32(id)
}
slog.Debug("stopChannels", slog.String("result", strings.Join(result, ",")))
// 删除过期的 channel
body, err := json.Marshal(map[string]any{
"by_ids": ids,
})
if err != nil {
return err
}
req, err := http.NewRequest(
http.MethodPost,
RemoveEndpoint,
strings.NewReader(string(body)),
)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth("tasks", "tasks")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return errors.New("failed to stop channels: " + string(body))
}
// 删除 redis 中的 channel
_, err = rds.Client.ZRemRangeByScore(ctx, "tasks:channel", "0", strconv.FormatInt(curr.Unix(), 10)).Result()
return nil
}

90
docs/docker-deployment.md Normal file
View File

@@ -0,0 +1,90 @@
# Docker 部署说明
本文档说明如何使用 Docker 构建和部署平台服务。
## 构建镜像
在项目根目录下执行以下命令构建 Docker 镜像:
```bash
docker build -t platform:latest .
```
## 生产环境部署
由于涉及敏感的 `.pem` 证书文件,这些文件不包含在代码库或 Docker 镜像中,而是在运行时通过卷挂载的方式提供。
### 准备证书文件
1. 在生产服务器上创建一个目录用于存放证书文件,例如:`/path/to/certs/`
2. 将必要的证书文件放入此目录:
- `pub_key.pem`
- `apiclient_key.pem`
### 运行容器
使用以下命令运行容器,挂载证书目录:
```bash
docker run -d \
--name platform \
-p 8080:8080 \
-e APP_PORT=8080 \
-v /path/to/certs:/app/certs \
platform:latest
```
### 环境变量
可以通过环境变量来配置应用程序:
- `APP_PORT`: 应用监听的端口号(默认: 8080
- 其他应用相关的环境变量可以通过 `-e` 参数添加
### 证书路径配置
如果应用程序需要知道证书的路径,可以通过环境变量配置:
```bash
docker run -d \
--name platform \
-p 8080:8080 \
-e APP_PORT=8080 \
-e PUB_KEY_PATH=/app/certs/pub_key.pem \
-e APICLIENT_KEY_PATH=/app/certs/apiclient_key.pem \
-v /path/to/certs:/app/certs \
platform:latest
```
## 使用 Docker Compose
也可以通过 Docker Compose 进行部署,创建 `docker-compose.yml` 文件:
```yaml
version: '3'
services:
platform:
image: platform:latest
ports:
- "8080:8080"
environment:
- APP_PORT=8080
- PUB_KEY_PATH=/app/certs/pub_key.pem
- APICLIENT_KEY_PATH=/app/certs/apiclient_key.pem
volumes:
- /path/to/certs:/app/certs
restart: unless-stopped
```
然后执行:
```bash
docker-compose up -d
```
## 安全建议
1. 确保证书文件的权限设置正确,仅允许必要的用户访问
2. 在生产环境中考虑使用 Docker Secrets 或 Kubernetes Secrets 来管理敏感信息
3. 定期更新证书和密钥

8
go.mod
View File

@@ -3,8 +3,8 @@ module platform
go 1.24.0
require (
github.com/alibabacloud-go/darabonba-openapi v0.2.1
github.com/alibabacloud-go/dysmsapi-20180501/v2 v2.0.6
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7
github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.3
github.com/alicebob/miniredis/v2 v2.34.0
github.com/glebarez/sqlite v1.11.0
github.com/gofiber/fiber/v2 v2.52.6
@@ -27,15 +27,11 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.3 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
github.com/alibabacloud-go/tea v1.3.8 // indirect
github.com/alibabacloud-go/tea-utils v1.4.3 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect
github.com/aliyun/credentials-go v1.4.5 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect

13
go.sum
View File

@@ -15,15 +15,11 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC
github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY=
github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10/go.mod h1:26a14FGhZVELuz2cc2AolvW4RHmIO3/HRwsdHhaIPDE=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 h1:ASXSBga98QrGMxbIThCD6jAti09gedLfvry6yJtsoBE=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7/go.mod h1:TBpgqm3XofZz2LCYjZhektGPU7ArEgascyzbm4SjFo4=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
@@ -32,11 +28,8 @@ github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA
github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.3 h1:32N2pGk28weVZ5/rjNk9gPx/jrRkR0rX9i8Id6IlyUY=
github.com/alibabacloud-go/dysmsapi-20170525/v4 v4.1.3/go.mod h1:gPbHx4BTxLIDNRfYNGGmp6aIpeNBamtdDlPcK4UTUto=
github.com/alibabacloud-go/dysmsapi-20180501/v2 v2.0.6 h1:XPck0S+7I8se2e8YnjA/D9OE6FzXwWo2UjlSziJs+z0=
github.com/alibabacloud-go/dysmsapi-20180501/v2 v2.0.6/go.mod h1:Ia7UzBNwNCeNR3TxGQAWi6yNttIFWGiR4HzIlA3Dasc=
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28=
github.com/alibabacloud-go/openapi-util v0.1.1/go.mod h1:/UehBSE2cf1gYT43GV4E+RxTdLRzURImCYY0aRmlXpw=
@@ -45,20 +38,15 @@ github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeG
github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk=
github.com/alibabacloud-go/tea v1.3.8 h1:Sk2+BDJC//xJ1/Eljf+Dlg2u2tgWpA9P7mlb87AEcEs=
github.com/alibabacloud-go/tea v1.3.8/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg=
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
github.com/alibabacloud-go/tea-utils v1.4.3 h1:8SzwmmRrOnQ09Hf5a9GyfJc0d7Sjv6fmsZoF4UDbFjo=
github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4=
github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0=
github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I=
github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0=
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
@@ -67,7 +55,6 @@ github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqR
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
github.com/aliyun/credentials-go v1.3.10/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/aliyun/credentials-go v1.4.5 h1:O76WYKgdy1oQYYiJkERjlA2dxGuvLRrzuO2ScrtGWSk=
github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=