optimize: using alpine and builder stages in dockerfile

This commit is contained in:
Zhang Minghan 2024-01-25 10:50:58 +08:00
parent 196f150eed
commit 13830a1e42
8 changed files with 50 additions and 37 deletions

View File

@ -1,34 +1,13 @@
FROM centos:7.8.2003
# Author: ProgramZmh
# License: Apache-2.0
# Description: Dockerfile for chatnio
# Install dependencies
RUN yum -y update && \
yum install -y epel-release gcc make libgcc libstdc++ wget
FROM golang:1.20 AS backend
# Install golang
RUN wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz && \
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz && \
rm -rf go1.21.5.linux-amd64.tar.gz
# Install nodejs
RUN wget https://nodejs.org/dist/v16.14.0/node-v16.14.0-linux-x64.tar.xz && \
rm -rf /usr/local/node && tar -C /usr/local -xJf node-v16.14.0-linux-x64.tar.xz && \
rm -rf node-v16.14.0-linux-x64.tar.xz && \
mv /usr/local/node-v16.14.0-linux-x64 /usr/local/node
ENV PATH=$PATH:/usr/local/go/bin:/usr/local/node/bin
# Copy source code
WORKDIR /backend
COPY . .
# Set ulimit in container and max open files
RUN ulimit -n 65535 && \
echo "* soft nofile 65535" >> /etc/security/limits.conf && \
echo "* hard nofile 65535" >> /etc/security/limits.conf && \
echo "ulimit -n 65535" >> /etc/profile && \
echo "ulimit -n 65535" >> /etc/rc.local
# set go proxy to https://goproxy.cn (open for vps in China Mainland)
# Set go proxy to https://goproxy.cn (open for vps in China Mainland)
# RUN go env -w GOPROXY=https://goproxy.cn,direct
ENV GOOS=linux GOARCH=amd64 GO111MODULE=on CGO_ENABLED=1
@ -36,15 +15,36 @@ ENV GOOS=linux GOARCH=amd64 GO111MODULE=on CGO_ENABLED=1
RUN go install && \
go build .
# Build frontend
FROM node:18 AS frontend
WORKDIR /app
COPY ./app .
RUN npm install -g pnpm && \
cd /app && \
pnpm install && \
pnpm run build && \
rm -rf node_modules
rm -rf node_modules src
FROM alpine
# Install dependencies
RUN apk update && \
apk upgrade && \
apk add --no-cache wget ca-certificates tzdata && \
update-ca-certificates 2>/dev/null || true && \
rm -rf /var/cache/apk/*
# Set timezone
RUN echo "Asia/Shanghai" > /etc/timezone && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# Copy dist
COPY --from=backend /backend /
COPY --from=frontend /app/dist /app/dist
# Expose port
EXPOSE 8094
# Start backend
# Run application
CMD ["./chat"]

View File

@ -25,7 +25,7 @@ function Tips({ content, children, className, hideTimeout }: TipsProps) {
const comp = useMemo(
() => (
<>
{content && <p>{content}</p>}
{content && <p className={`text-center`}>{content}</p>}
{children}
</>
),

View File

@ -3,6 +3,7 @@ import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Loader2 } from "lucide-react";
import { UserTypeChartResponse } from "@/admin/types.ts";
import Tips from "@/components/Tips.tsx";
type UserTypeChartProps = {
data: UserTypeChartResponse;
@ -60,7 +61,10 @@ function UserTypeChart({ data, dark }: UserTypeChartProps) {
<div className={`chart`}>
<p className={`chart-title mb-2`}>
<p className={`flex flex-row items-center w-full`}>
<p>{t("admin.user-type-chart")}</p>
<p>
{t("admin.user-type-chart")}
<Tips content={t("admin.user-type-chart-tip")} />
</p>
<p className={`text-sm ml-auto chart-title-info`}>
{t("admin.user-type-chart-info", { total: data.total })}
</p>

View File

@ -15,6 +15,7 @@ import { AnnouncementEvent, announcementEvent } from "@/events/announcement.ts";
import { Bell, Check } from "lucide-react";
import Markdown from "@/components/Markdown.tsx";
import { Button } from "@/components/ui/button.tsx";
import { cn } from "@/components/ui/lib/utils.ts";
function Announcement() {
const { t } = useTranslation();
@ -31,7 +32,11 @@ function Announcement() {
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger asChild>
<Button variant={`outline`} size={`icon`}>
<Button
variant={`outline`}
size={`icon`}
className={cn(!announcement.length && `hidden`)}
>
<Bell className={`h-4 w-4`} />
</Button>
</AlertDialogTrigger>

View File

@ -353,6 +353,7 @@
"model-chart-tip": "Token 用量",
"model-usage-chart": "模型使用占比",
"user-type-chart": "用户类型占比",
"user-type-chart-tip": "其他付费用户:指订阅过期用户或点数超过当前初始点数的用户(使用邀请码等操作也会被算作点数增加的变更)",
"user-type-chart-info": "总共 {{total}} 用户",
"request-chart": "请求量统计",
"billing-chart": "收入统计",

View File

@ -558,7 +558,8 @@
"standard_plan": "Standard Subscribers",
"pro_plan": "Pro Subscribers"
},
"user-type-chart-info": "Total {{total}} users"
"user-type-chart-info": "Total {{total}} users",
"user-type-chart-tip": "Other paying users: refers to users who subscribe to expired users or users whose points exceed the current initial points (operations such as using invitation codes will also be counted as changes in points increase)"
},
"mask": {
"title": "Mask Settings",

View File

@ -558,7 +558,8 @@
"standard_plan": "標準サブスクライバー",
"pro_plan": "Pro Subscribers"
},
"user-type-chart-info": "合計{{total}}ユーザー"
"user-type-chart-info": "合計{{total}}ユーザー",
"user-type-chart-tip": "他の有料ユーザー:有効期限切れのユーザーまたはポイントが現在の初期ポイントを超えるユーザーをサブスクライブするユーザーを指します(招待コードを使用するなどの操作もポイントの増加としてカウントされます)"
},
"mask": {
"title": "プリセット設定",

View File

@ -558,7 +558,8 @@
"standard_plan": "Стандартные подписчики",
"pro_plan": "Подписчики Pro"
},
"user-type-chart-info": "Всего пользователей: {{total}}"
"user-type-chart-info": "Всего пользователей: {{total}}",
"user-type-chart-tip": "Другие платящие пользователи: относится к пользователям, которые подписываются на пользователей с истекшим сроком действия или пользователей, чьи баллы превышают текущие начальные баллы (такие операции, как использование кодов приглашений, также будут учитываться при увеличении изменений в баллах)"
},
"mask": {
"title": "Настройки маски",