🐳 optimized docker packaging

This commit is contained in:
2025-01-23 19:10:56 +08:00
parent fc95d73adb
commit a3d4f2c8d1
5 changed files with 64 additions and 68 deletions

4
.idea/GOHCache.xml generated
View File

@@ -1489,7 +1489,7 @@
<entry key="file://$PROJECT_DIR$/app/aisvc/rpc/internal/logic/aiservice/face_recognition_logic.go">
<value>
<ScannedPath>
<option name="lastModified" value="1737604866085" />
<option name="lastModified" value="1737629887959" />
<option name="schema">
<list>
<option value="FaceRecognitionLogic" />
@@ -2117,7 +2117,7 @@
<entry key="file://$PROJECT_DIR$/app/auth/api/internal/logic/storage/upload_file_logic.go">
<value>
<ScannedPath>
<option name="lastModified" value="1737533110977" />
<option name="lastModified" value="1737629820919" />
<option name="schema">
<list>
<option value="UploadFileLogic" />

View File

@@ -9,18 +9,14 @@ LABEL maintainer="landaiqing <<landaiqing@126.com>>"
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list && \
apt-get update && apt-get install -y --no-install-recommends --fix-missing \
tzdata git build-essential cmake pkg-config wget unzip libgtk2.0-dev \
curl ca-certificates libcurl4-openssl-dev libssl-dev \
libavcodec-dev libavformat-dev libswscale-dev libtbb2 libtbb-dev \
libharfbuzz-dev libfreetype6-dev \
libjpeg-dev libturbojpeg-dev libpng-dev libtiff-dev libdc1394-22-dev nasm \
libdlib-dev libblas-dev libatlas-base-dev liblapack-dev \
gcc g++ musl-dev cmake && \
rm -rf /var/lib/apt/lists/*
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list && \
apt-get update && apt-get install -y --no-install-recommends \
tzdata git build-essential cmake pkg-config unzip curl ca-certificates \
libcurl4-openssl-dev libssl-dev libturbojpeg-dev \
libpng-dev libtiff-dev nasm libblas-dev libatlas-base-dev\
libdlib-dev libjpeg62-turbo-dev liblapack-dev && \
rm -rf /var/lib/apt/lists/*
ARG OPENCV_VERSION="4.11.0"
@@ -71,8 +67,6 @@ WORKDIR /app
COPY . .
#WORKDIR /app/app/aisvc/
ENV CGO_ENABLED=1 \
CGO_CFLAGS="-I/usr/local/include/opencv4" \
CGO_CPPFLAGS="-I/usr/local/include" \
@@ -81,13 +75,8 @@ ENV CGO_ENABLED=1 \
GOARCH=amd64 \
GOPROXY=https://goproxy.cn,direct
RUN go mod download
RUN go build -ldflags="-w -s" -o schisandra-ai-server ./app/aisvc/rpc/aisvc.go
#EXPOSE 8888
#
#CMD ["./schisandra-ai-server"]
RUN go mod download && \
go build -ldflags="-w -s" -o schisandra-ai-server ./app/aisvc/rpc/aisvc.go
FROM debian:bullseye-slim AS runtime
@@ -96,17 +85,13 @@ ENV TZ=Asia/Shanghai \
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
apt-get update && apt-get install -y --no-install-recommends \
tzdata libjpeg62-turbo libpng16-16 libtiff5 libturbojpeg0 \
libharfbuzz0b libfreetype6 libavcodec58 libavformat58 libswscale5 libtbb2 \
libblas3 liblapack3 && \
tzdata libjpeg62-turbo libblas3 liblapack3 libdlib-dev libtiff5 && \
rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /usr/local/lib /usr/local/lib/
COPY --from=builder /usr/lib/ /usr/lib/
COPY --from=builder /usr/local/include/opencv4 /usr/local/include/opencv4/
COPY --from=builder /app/schisandra-ai-server .
@@ -117,9 +102,6 @@ COPY --from=builder /app/app/aisvc/resources ./resources
ENV LD_LIBRARY_PATH=/usr/local/lib
RUN echo "/usr/local/lib" > /etc/ld.so.conf.d/custom-libs.conf && ldconfig
EXPOSE 8888
CMD ["./schisandra-ai-server"]

View File

@@ -10,6 +10,7 @@ import (
"github.com/zeromicro/go-zero/core/logx"
"image"
"image/jpeg"
_ "image/png"
"os"
"path/filepath"
"schisandra-album-cloud-microservices/app/aisvc/model/mysql/model"
@@ -47,6 +48,9 @@ func (l *FaceRecognitionLogic) FaceRecognition(in *pb.FaceRecognitionRequest) (*
if err != nil {
return nil, err
}
if toJPEG == nil {
return nil, nil
}
// 提取人脸特征
faceFeatures, err := l.svcCtx.FaceRecognizer.RecognizeSingle(toJPEG)
if err != nil {
@@ -96,18 +100,21 @@ func (l *FaceRecognitionLogic) FaceRecognition(in *pb.FaceRecognitionRequest) (*
return l.saveNewFace(in, faceFeatures, hashKey)
}
// ConvertImageToJPEG 将非 JPEG 格式的图片字节数据转换为 JPEG
func (l *FaceRecognitionLogic) ConvertImageToJPEG(imageData []byte) ([]byte, error) {
// 使用 image.Decode 解码图像数据
img, _, err := image.Decode(bytes.NewReader(imageData))
// 解码图片
img, format, err := image.Decode(bytes.NewReader(imageData))
if err != nil {
return nil, fmt.Errorf("failed to decode image: %v", err)
}
// 创建一个缓冲区来存储 JPEG 格式数据
var jpegBuffer bytes.Buffer
// 如果已经是 JPEG 格式,则直接返回原数据
if format == "jpeg" {
return imageData, nil
}
// 将图片编码为 JPEG 格式
// 如果是 PNG 格式,则转换为 JPEG
var jpegBuffer bytes.Buffer
err = jpeg.Encode(&jpegBuffer, img, nil)
if err != nil {
return nil, fmt.Errorf("failed to encode image to JPEG: %v", err)

View File

@@ -56,26 +56,29 @@ func (l *UploadFileLogic) UploadFile(r *http.Request) (resp string, err error) {
if err != nil {
return "", err
}
var faceId int64
var faceId int64 = 0
var className string
bytes, err := io.ReadAll(file)
if err != nil {
return "", err
}
// 人脸识别
face, err := l.svcCtx.AiSvcRpc.FaceRecognition(l.ctx, &pb.FaceRecognitionRequest{Face: bytes, UserId: uid})
if err != nil {
return "", err
if result.FileType == "image/png" || result.FileType == "image/jpeg" {
face, err := l.svcCtx.AiSvcRpc.FaceRecognition(l.ctx, &pb.FaceRecognitionRequest{Face: bytes, UserId: uid})
if err != nil {
return "", err
}
if face != nil {
faceId = face.GetFaceId()
}
// 图像分类
classification, err := l.svcCtx.AiSvcRpc.TfClassification(l.ctx, &pb.TfClassificationRequest{Image: bytes})
if err != nil {
return "", err
}
className = classification.GetClassName()
}
if face != nil {
faceId = face.GetFaceId()
}
// 分类
classification, err := l.svcCtx.AiSvcRpc.TfClassification(l.ctx, &pb.TfClassificationRequest{Image: bytes})
if err != nil {
return "", err
}
fmt.Println(classification.ClassName)
fmt.Println(classification.Score)
// 解析 EXIF 信息
exif, err := l.parseExifData(result.Exif)
@@ -99,12 +102,13 @@ func (l *UploadFileLogic) UploadFile(r *http.Request) (resp string, err error) {
}
// 上传文件到 OSS
if err = l.uploadFileToOSS(uid, header, file); err != nil {
bucket, provider, err := l.uploadFileToOSS(uid, header, file)
if err != nil {
return "", err
}
// 将 EXIF 和文件信息存入数据库
if err = l.saveFileInfoToDB(uid, header, result, originalDateTime, gpsString, locationString, exif, faceId); err != nil {
if err = l.saveFileInfoToDB(uid, bucket, provider, header, result, originalDateTime, gpsString, locationString, exif, faceId, className); err != nil {
return "", err
}
@@ -220,20 +224,20 @@ func (l *UploadFileLogic) getGeoLocation(latitude, longitude float64) (string, s
}
// 上传文件到 OSS
func (l *UploadFileLogic) uploadFileToOSS(uid string, header *multipart.FileHeader, file multipart.File) error {
func (l *UploadFileLogic) uploadFileToOSS(uid string, header *multipart.FileHeader, file multipart.File) (string, string, error) {
ossConfig := l.svcCtx.DB.ScaStorageConfig
dbConfig, err := ossConfig.Where(ossConfig.UserID.Eq(uid)).First()
if err != nil {
return errors.New("oss config not found")
return "", "", errors.New("oss config not found")
}
accessKey, err := encrypt.Decrypt(dbConfig.AccessKey, l.svcCtx.Config.Encrypt.Key)
if err != nil {
return errors.New("decrypt access key failed")
return "", "", errors.New("decrypt access key failed")
}
secretKey, err := encrypt.Decrypt(dbConfig.SecretKey, l.svcCtx.Config.Encrypt.Key)
if err != nil {
return errors.New("decrypt secret key failed")
return "", "", errors.New("decrypt secret key failed")
}
storageConfig := &config.StorageConfig{
@@ -247,31 +251,34 @@ func (l *UploadFileLogic) uploadFileToOSS(uid string, header *multipart.FileHead
service, err := l.svcCtx.StorageManager.GetStorage(uid, storageConfig)
if err != nil {
return errors.New("get storage failed")
return "", "", errors.New("get storage failed")
}
_, err = service.UploadFileSimple(l.ctx, dbConfig.Bucket, header.Filename, file, map[string]string{})
if err != nil {
return errors.New("upload file failed")
return "", "", errors.New("upload file failed")
}
return nil
return dbConfig.Bucket, dbConfig.Type, nil
}
// 将 EXIF 和文件信息存入数据库
func (l *UploadFileLogic) saveFileInfoToDB(uid string, header *multipart.FileHeader, result types.File, originalDateTime, gpsString, locationString string, exif map[string]interface{}, faceId int64) error {
func (l *UploadFileLogic) saveFileInfoToDB(uid, bucket, provider string, header *multipart.FileHeader, result types.File, originalDateTime, gpsString, locationString string, exif map[string]interface{}, faceId int64, className string) error {
exifJSON, err := json.Marshal(exif)
if err != nil {
return errors.New("marshal exif failed")
}
var landscape string
if result.Landscape != "none" {
landscape = result.Landscape
}
scaStorageInfo := &model.ScaStorageInfo{
UserID: uid,
Provider: result.FileType,
Bucket: result.TopCategory,
Provider: provider,
Bucket: bucket,
FileName: header.Filename,
FileSize: strconv.FormatInt(header.Size, 10),
FileType: result.FileType,
Landscape: result.Landscape,
Landscape: landscape,
Objects: strings.Join(result.ObjectArray, ", "),
Anime: strconv.FormatBool(result.IsAnime),
Category: result.TopCategory,
@@ -281,6 +288,7 @@ func (l *UploadFileLogic) saveFileInfoToDB(uid string, header *multipart.FileHea
Location: locationString,
Exif: string(exifJSON),
FaceID: faceId,
Tags: className,
}
err = l.svcCtx.DB.ScaStorageInfo.Create(scaStorageInfo)

View File

@@ -28,9 +28,8 @@ FROM alpine:latest
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add --no-cache tzdata libjpeg-turbo
WORKDIR /app