├── .github └── workflows │ └── docker.yml ├── README.md ├── build.md ├── docker ├── 1.6.0 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ ├── mm.config.js │ │ └── vue.config.js │ └── server │ │ └── main.go ├── 2.0.0 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ └── vite.config.ts │ └── server │ │ └── main.go ├── 2.0.1 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ └── vite.config.ts │ └── server │ │ └── main.go ├── 2.0.2 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ └── vite.config.ts │ └── server │ │ └── main.go ├── 2.0.3 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ └── vite.config.ts │ └── server │ │ └── main.go ├── 2.0.4 │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ │ └── vite.config.ts │ └── server │ │ └── main.go └── latest │ ├── .env │ ├── Dockerfile.base │ ├── Dockerfile.nginx │ ├── Dockerfile.standalone │ ├── Dockerfile.static │ ├── patch │ └── vite.config.ts │ └── server │ └── main.go └── scripts ├── build-base-image.sh ├── build-multiarch.sh ├── build-nginx.sh ├── build-standalone.sh ├── build-static.sh └── push-images.sh /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Build and Push Docker Images 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up QEMU 17 | uses: docker/setup-qemu-action@v3 18 | 19 | - name: Set up Docker Buildx 20 | uses: docker/setup-buildx-action@v3 21 | 22 | - name: Log in to Docker Hub 23 | uses: docker/login-action@v3 24 | with: 25 | username: ${{ secrets.DOCKER_USERNAME }} 26 | password: ${{ secrets.DOCKER_PASSWORD }} 27 | 28 | - name: Build and push multi-arch images 29 | run: | 30 | chmod +x scripts/build-multiarch.sh 31 | bash scripts/build-multiarch.sh -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker MD 2 | 3 | [![docker](https://img.shields.io/badge/docker-latest-42cc23?style=flat-square&labelColor=564341)](https://hub.docker.com/r/doocs/md) 4 | 5 | 轻量的微信编辑器 [doocs/md](https://github.com/doocs/md) 的轻量容器镜像。 6 | 7 | # 目录结构 8 | 9 | ```bash 10 | ├── docker 镜像文件目录(包含最新分支和 1.6.0 之后的版本) 11 | │   ├── 1.6.0 12 | │   ├── 2.0.0 13 | │   ├── 2.0.1 14 | │   ├── 2.0.2 15 | │   ├── 2.0.3 16 | │   ├── 2.0.4 17 | │   └── latest 18 | └── scripts 构建镜像使用的脚本 19 | ├── build-base-image.sh 构建基础镜像 20 | ├── build-nginx.sh 构建基于 Nginx 的镜像 21 | ├── build-standalone.sh 构建独立二进制版本 22 | └── build-multiarch.sh 构建多架构镜像(linux/amd64,linux/arm64) 23 | ``` 24 | 25 | ## 镜像列表 26 | 27 | ### 二进制版 28 | 29 | 镜像命名规则 `doocs/md:[版本号]` 30 | 31 | ```bash 32 | docker run --rm -it -p 8080:80 doocs/md:latest 33 | docker run --rm -it -p 8080:80 doocs/md:2.0.4 34 | docker run --rm -it -p 8080:80 doocs/md:2.0.3 35 | docker run --rm -it -p 8080:80 doocs/md:2.0.2 36 | docker run --rm -it -p 8080:80 doocs/md:2.0.1 37 | docker run --rm -it -p 8080:80 doocs/md:2.0.0 38 | docker run --rm -it -p 8080:80 doocs/md:1.6.0 39 | ``` 40 | 41 | ### Nginx 镜像版 42 | 43 | 镜像命名规则 `doocs/md:[版本号]-nginx` 44 | 45 | ```bash 46 | docker run --rm -it -p 8080:80 doocs/md:latest-nginx 47 | docker run --rm -it -p 8080:80 doocs/md:2.0.3-nginx 48 | docker run --rm -it -p 8080:80 doocs/md:2.0.2-nginx 49 | docker run --rm -it -p 8080:80 doocs/md:2.0.1-nginx 50 | docker run --rm -it -p 8080:80 doocs/md:2.0.0-nginx 51 | docker run --rm -it -p 8080:80 doocs/md:1.6.0-nginx 52 | ``` 53 | -------------------------------------------------------------------------------- /build.md: -------------------------------------------------------------------------------- 1 | # Docker 镜像 2 | 3 | ## 构建镜像并发布 4 | 5 | ### 0. Docker 账号登录 6 | 7 | 执行以下命令,登录 Docker 账号: 8 | 9 | ```bash 10 | docker login -u -p 11 | ``` 12 | 13 | ### 1. 构建镜像 14 | 15 | 分别执行以下三个命令: 16 | 17 | ```bash 18 | bash scripts/build-base-image.sh 19 | ``` 20 | 21 | ```bash 22 | bash scripts/build-nginx.sh 23 | ``` 24 | 25 | ```bash 26 | bash scripts/build-standalone.sh 27 | ``` 28 | 29 | ### 2. 推送镜像 30 | 31 | 构建出工具镜像后,执行以下命令: 32 | 33 | ```bash 34 | bash scripts/push-images.sh 35 | ``` 36 | 37 | 将镜像推送至 Docker Hub。 38 | 39 | ## 拉取、运行镜像 40 | 41 | 执行以下命令进行镜像拉取: 42 | 43 | ```bash 44 | docker pull doocs/md:latest 45 | ``` 46 | 47 | 运行镜像: 48 | 49 | ```bash 50 | docker run -d -p 8080:80 doocs/md:latest 51 | ``` -------------------------------------------------------------------------------- /docker/1.6.0/.env: -------------------------------------------------------------------------------- 1 | VER_APP=1.6.0 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/1.6.0/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:17-alpine3.14 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 1.6.0 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vue.config.js /app/vue.config.js 11 | COPY ./patch/mm.config.js /app/mm/mm.config.js 12 | ENV NODE_OPTIONS="--openssl-legacy-provider" 13 | RUN npm i && npm run build 14 | 15 | FROM scratch 16 | LABEL MAINTAINER="ylb" 17 | COPY --from=builder /app/dist /app/assets -------------------------------------------------------------------------------- /docker/1.6.0/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=1.6.0 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/1.6.0/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=1.6.0 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/1.6.0/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=1.6.0 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/1.6.0/patch/mm.config.js: -------------------------------------------------------------------------------- 1 | const fs = require(`fs`) 2 | const path = require(`path`) 3 | 4 | const { dcloud } = require(`./util.js`) 5 | 6 | // unicloud 服务空间配置 7 | const spaceInfo = { 8 | spaceId: ``, 9 | clientSecret: ``, 10 | } 11 | 12 | /** 13 | * 配置说明请参考文档: 14 | * https://hongqiye.com/doc/mockm/config/option.html 15 | * @type {import('mockm/@types/config').Config} 16 | */ 17 | module.exports = util => { 18 | const port = 9000 19 | return { 20 | port, 21 | testPort: 9005, 22 | replayPort: 9001, 23 | watch: [`./util.js`], 24 | api: { 25 | async '/upload'(req, res) { 26 | const multiparty = await util.toolObj.generate.initPackge(`multiparty`) 27 | const form = new multiparty.Form({ 28 | uploadDir: `../public/upload/`, 29 | }) 30 | form.parse(req, async (err, fields = [], files) => { 31 | const file = files.file[0] 32 | let url = `http://127.0.0.1:${port}/public/upload/${path.parse(file.path).base}` 33 | try { 34 | url = await dcloud(spaceInfo)({name: file.originalFilename, file: fs.createReadStream(file.path)}) 35 | } catch (err) { 36 | // console.log(err) 37 | } 38 | res.json({url}) 39 | }) 40 | }, 41 | }, 42 | static: [ 43 | { 44 | fileDir: `../dist`, 45 | path: `/`, 46 | }, 47 | ], 48 | } 49 | } -------------------------------------------------------------------------------- /docker/1.6.0/patch/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | publicPath: "/", 3 | configureWebpack: (config) => { 4 | config.module.rules.push({ 5 | test: /\.(txt|md)$/i, 6 | use: [ 7 | { 8 | loader: "raw-loader", 9 | }, 10 | ], 11 | }); 12 | }, 13 | productionSourceMap: false, 14 | css: { 15 | sourceMap: false, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /docker/1.6.0/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/2.0.0/.env: -------------------------------------------------------------------------------- 1 | VER_APP=2.0.0 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/2.0.0/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 2.0.0 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vite.config.ts /app/vite.config.ts 11 | ENV NODE_OPTIONS="--openssl-legacy-provider" 12 | RUN npm i && npm run build 13 | 14 | FROM scratch 15 | LABEL MAINTAINER="ylb" 16 | COPY --from=builder /app/dist /app/assets 17 | -------------------------------------------------------------------------------- /docker/2.0.0/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.0 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/2.0.0/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.0 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/2.0.0/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.0 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/2.0.0/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | // https://vitejs.dev/config/ 15 | export default defineConfig({ 16 | base: `/`, // 基本路径, 建议以绝对路径跟随访问目录 17 | define: { 18 | process, 19 | }, 20 | plugins: [ 21 | vue(), 22 | UnoCSS(), 23 | vueDevTools(), 24 | nodePolyfills({ 25 | include: [`path`, `util`, `timers`, `stream`, `fs`], 26 | overrides: { 27 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 28 | // fs: 'memfs', 29 | }, 30 | }), 31 | VitePluginRadar({ 32 | analytics: { 33 | id: `G-7NZL3PZ0NK`, 34 | } 35 | }), 36 | process.env.ANALYZE === `true` && visualizer({ 37 | emitFile: true, 38 | filename: `stats.html`, 39 | }), 40 | AutoImport({ 41 | imports: [ 42 | `vue`, 43 | `pinia`, 44 | `@vueuse/core`, 45 | ], 46 | dirs: [ 47 | `./src/stores`, 48 | `./src/utils/toast`, 49 | ], 50 | }), 51 | Components({ 52 | resolvers: [], 53 | }), 54 | ], 55 | resolve: { 56 | alias: { 57 | '@': path.resolve(__dirname, `./src`), 58 | }, 59 | }, 60 | css: { 61 | devSourcemap: true, 62 | }, 63 | build: { 64 | rollupOptions: { 65 | output: { 66 | chunkFileNames: `static/js/md-[name]-[hash].js`, 67 | entryFileNames: `static/js/md-[name]-[hash].js`, 68 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 69 | }, 70 | }, 71 | }, 72 | }) 73 | -------------------------------------------------------------------------------- /docker/2.0.0/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/2.0.1/.env: -------------------------------------------------------------------------------- 1 | VER_APP=2.0.1 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/2.0.1/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 2.0.1 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vite.config.ts /app/vite.config.ts 11 | ENV NODE_OPTIONS="--openssl-legacy-provider" 12 | RUN npm i && npm run build 13 | 14 | FROM scratch 15 | LABEL MAINTAINER="ylb" 16 | COPY --from=builder /app/dist /app/assets 17 | -------------------------------------------------------------------------------- /docker/2.0.1/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.1 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/2.0.1/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.1 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/2.0.1/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.1 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/2.0.1/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | // https://vitejs.dev/config/ 15 | export default defineConfig({ 16 | base: `/`, // 基本路径, 建议以绝对路径跟随访问目录 17 | define: { 18 | process, 19 | }, 20 | envPrefix: [`VITE_`, `CF_`], // 允许 VITE_ 和 CF_ 前缀的变量 21 | plugins: [ 22 | vue(), 23 | UnoCSS(), 24 | vueDevTools(), 25 | nodePolyfills({ 26 | include: [`path`, `util`, `timers`, `stream`, `fs`], 27 | overrides: { 28 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 29 | // fs: 'memfs', 30 | }, 31 | }), 32 | VitePluginRadar({ 33 | analytics: { 34 | id: `G-7NZL3PZ0NK`, 35 | }, 36 | }), 37 | process.env.ANALYZE === `true` && visualizer({ 38 | emitFile: true, 39 | filename: `stats.html`, 40 | }), 41 | AutoImport({ 42 | imports: [ 43 | `vue`, 44 | `pinia`, 45 | `@vueuse/core`, 46 | ], 47 | dirs: [ 48 | `./src/stores`, 49 | `./src/utils/toast`, 50 | ], 51 | }), 52 | Components({ 53 | resolvers: [], 54 | }), 55 | ], 56 | resolve: { 57 | alias: { 58 | '@': path.resolve(__dirname, `./src`), 59 | }, 60 | }, 61 | css: { 62 | devSourcemap: true, 63 | }, 64 | build: { 65 | rollupOptions: { 66 | output: { 67 | chunkFileNames: `static/js/md-[name]-[hash].js`, 68 | entryFileNames: `static/js/md-[name]-[hash].js`, 69 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 70 | }, 71 | }, 72 | }, 73 | }) 74 | -------------------------------------------------------------------------------- /docker/2.0.1/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/2.0.2/.env: -------------------------------------------------------------------------------- 1 | VER_APP=2.0.2 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/2.0.2/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 2.0.2 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vite.config.ts /app/vite.config.ts 11 | ENV NODE_OPTIONS="--openssl-legacy-provider" 12 | RUN npm i && npm run build 13 | 14 | FROM scratch 15 | LABEL MAINTAINER="ylb" 16 | COPY --from=builder /app/dist /app/assets 17 | -------------------------------------------------------------------------------- /docker/2.0.2/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.2 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/2.0.2/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.2 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/2.0.2/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.2 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/2.0.2/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | // https://vitejs.dev/config/ 15 | export default defineConfig({ 16 | base: `/`, // 基本路径, 建议以绝对路径跟随访问目录 17 | define: { 18 | process, 19 | }, 20 | envPrefix: [`VITE_`, `CF_`], // 允许 VITE_ 和 CF_ 前缀的变量 21 | plugins: [ 22 | vue(), 23 | UnoCSS(), 24 | vueDevTools(), 25 | nodePolyfills({ 26 | include: [`path`, `util`, `timers`, `stream`, `fs`], 27 | overrides: { 28 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 29 | // fs: 'memfs', 30 | }, 31 | }), 32 | VitePluginRadar({ 33 | analytics: { 34 | id: `G-7NZL3PZ0NK`, 35 | }, 36 | }), 37 | process.env.ANALYZE === `true` && visualizer({ 38 | emitFile: true, 39 | filename: `stats.html`, 40 | }), 41 | AutoImport({ 42 | imports: [ 43 | `vue`, 44 | `pinia`, 45 | `@vueuse/core`, 46 | ], 47 | dirs: [ 48 | `./src/stores`, 49 | `./src/utils/toast`, 50 | ], 51 | }), 52 | Components({ 53 | resolvers: [], 54 | }), 55 | ], 56 | resolve: { 57 | alias: { 58 | '@': path.resolve(__dirname, `./src`), 59 | }, 60 | }, 61 | css: { 62 | devSourcemap: true, 63 | }, 64 | build: { 65 | rollupOptions: { 66 | output: { 67 | chunkFileNames: `static/js/md-[name]-[hash].js`, 68 | entryFileNames: `static/js/md-[name]-[hash].js`, 69 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 70 | }, 71 | }, 72 | }, 73 | }) 74 | -------------------------------------------------------------------------------- /docker/2.0.2/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/2.0.3/.env: -------------------------------------------------------------------------------- 1 | VER_APP=2.0.3 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/2.0.3/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 2.0.3 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vite.config.ts /app/vite.config.ts 11 | ENV NODE_OPTIONS="--openssl-legacy-provider" 12 | RUN npm i && npm run build 13 | 14 | FROM scratch 15 | LABEL MAINTAINER="ylb" 16 | COPY --from=builder /app/dist /app/assets 17 | -------------------------------------------------------------------------------- /docker/2.0.3/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.3 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/2.0.3/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.3 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/2.0.3/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.3 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/2.0.3/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | // https://vitejs.dev/config/ 15 | export default defineConfig({ 16 | base: `/`, // 基本路径, 建议以绝对路径跟随访问目录 17 | define: { 18 | process, 19 | }, 20 | envPrefix: [`VITE_`, `CF_`], // 允许 VITE_ 和 CF_ 前缀的变量 21 | plugins: [ 22 | vue(), 23 | UnoCSS(), 24 | vueDevTools(), 25 | nodePolyfills({ 26 | include: [`path`, `util`, `timers`, `stream`, `fs`], 27 | overrides: { 28 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 29 | // fs: 'memfs', 30 | }, 31 | }), 32 | VitePluginRadar({ 33 | analytics: { 34 | id: `G-7NZL3PZ0NK`, 35 | }, 36 | }), 37 | process.env.ANALYZE === `true` && visualizer({ 38 | emitFile: true, 39 | filename: `stats.html`, 40 | }), 41 | AutoImport({ 42 | imports: [ 43 | `vue`, 44 | `pinia`, 45 | `@vueuse/core`, 46 | ], 47 | dirs: [ 48 | `./src/stores`, 49 | `./src/utils/toast`, 50 | ], 51 | }), 52 | Components({ 53 | resolvers: [], 54 | }), 55 | ], 56 | resolve: { 57 | alias: { 58 | '@': path.resolve(__dirname, `./src`), 59 | }, 60 | }, 61 | css: { 62 | devSourcemap: true, 63 | }, 64 | build: { 65 | rollupOptions: { 66 | output: { 67 | chunkFileNames: `static/js/md-[name]-[hash].js`, 68 | entryFileNames: `static/js/md-[name]-[hash].js`, 69 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 70 | }, 71 | }, 72 | }, 73 | }) 74 | -------------------------------------------------------------------------------- /docker/2.0.3/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/2.0.4/.env: -------------------------------------------------------------------------------- 1 | VER_APP=2.0.4 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/2.0.4/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | ARG VER_APP 2.0.4 7 | ENV VER $VER_APP 8 | RUN curl -L "https://github.com/doocs/md/archive/refs/tags/v$VER.zip" -o "v$VER.zip" && unzip "v$VER.zip" && mv "md-$VER" /app 9 | WORKDIR /app 10 | COPY ./patch/vite.config.ts /app/vite.config.ts 11 | ENV NODE_OPTIONS="--openssl-legacy-provider" 12 | RUN npm i && npm run build 13 | 14 | FROM scratch 15 | LABEL MAINTAINER="ylb" 16 | COPY --from=builder /app/dist /app/assets 17 | -------------------------------------------------------------------------------- /docker/2.0.4/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.4 2 | ARG VER_NGX="1.21.6-alpine" 3 | 4 | FROM --platform=$BUILDPLATFORM doocs/md:$VER_APP-assets AS assets 5 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 6 | LABEL MAINTAINER="ylb" 7 | COPY --from=assets /app/assets /usr/share/nginx/html 8 | -------------------------------------------------------------------------------- /docker/2.0.4/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.4 2 | ARG VER_GOLANG=1.17.6-alpine3.15 3 | ARG VER_ALPINE=3.15 4 | 5 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 6 | 7 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 8 | ARG TARGETARCH 9 | ARG TARGETOS 10 | COPY --from=assets /app/* /app/assets/ 11 | COPY server/main.go /app 12 | RUN apk add git bash gcc musl-dev upx 13 | WORKDIR /app 14 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 15 | RUN go build -ldflags "-w -s" -o md main.go && \ 16 | apk add upx && \ 17 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 18 | 19 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 20 | LABEL MAINTAINER="ylb" 21 | COPY --from=gobuilder /app/md.minify /bin/md 22 | EXPOSE 80 23 | CMD ["md"] 24 | -------------------------------------------------------------------------------- /docker/2.0.4/Dockerfile.static: -------------------------------------------------------------------------------- 1 | ARG VER_APP=2.0.4 2 | FROM --platform=$BUILDPLATFORM "doocs/md:$VER_APP-assets" AS assets 3 | 4 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 5 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 6 | 7 | WORKDIR /home/static 8 | 9 | COPY --from=assets /app/assets /home/static 10 | 11 | EXPOSE 80 12 | 13 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 14 | -------------------------------------------------------------------------------- /docker/2.0.4/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | export default defineConfig({ 15 | base: `/`, 16 | define: { process }, 17 | envPrefix: [`VITE_`, `CF_`], 18 | plugins: [ 19 | vue(), 20 | UnoCSS(), 21 | vueDevTools(), 22 | nodePolyfills({ 23 | include: [`path`, `util`, `timers`, `stream`, `fs`], 24 | overrides: { 25 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 26 | // fs: 'memfs', 27 | }, 28 | }), 29 | VitePluginRadar({ 30 | analytics: { id: `G-7NZL3PZ0NK` }, 31 | }), 32 | process.env.ANALYZE === `true` 33 | && visualizer({ emitFile: true, filename: `stats.html` }), 34 | AutoImport({ 35 | imports: [`vue`, `pinia`, `@vueuse/core`], 36 | dirs: [`./src/stores`, `./src/utils/toast`], 37 | }), 38 | Components({ 39 | resolvers: [], 40 | }), 41 | ], 42 | resolve: { 43 | alias: { '@': path.resolve(__dirname, `./src`) }, 44 | }, 45 | css: { devSourcemap: true }, 46 | build: { 47 | rollupOptions: { 48 | output: { 49 | chunkFileNames: `static/js/md-[name]-[hash].js`, 50 | entryFileNames: `static/js/md-[name]-[hash].js`, 51 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 52 | manualChunks(id) { 53 | if (id.includes(`node_modules`)) { 54 | if (id.includes(`katex`)) 55 | return `katex` 56 | if (id.includes(`mermaid`)) 57 | return `mermaid` 58 | if (id.includes(`cytoscape`)) 59 | return `cytoscape` 60 | if (id.includes(`highlight.js`)) 61 | return `hljs` 62 | const pkg = id 63 | .split(`node_modules/`)[1] 64 | .split(`/`)[0] 65 | .replace(`@`, `npm_`) 66 | return `vendor_${pkg}` 67 | } 68 | }, 69 | }, 70 | }, 71 | }, 72 | }) 73 | -------------------------------------------------------------------------------- /docker/2.0.4/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /docker/latest/.env: -------------------------------------------------------------------------------- 1 | VER_APP=latest 2 | VER_NGX=1.21.6-alpine 3 | VER_GOLANG=1.17.6-alpine3.15 4 | VER_ALPINE=3.15 -------------------------------------------------------------------------------- /docker/latest/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM node:20-alpine3.19 AS builder 2 | ENV LANG="en_US.UTF-8" 3 | ENV LANGUAGE="en_US.UTF-8" 4 | ENV LC_ALL="en_US.UTF-8" 5 | RUN apk add --no-cache curl unzip 6 | RUN curl -L "https://github.com/doocs/md/archive/refs/heads/main.zip" -o "main.zip" && unzip "main.zip" && mv "md-main" /app 7 | WORKDIR /app 8 | COPY ./patch/vite.config.ts /app/vite.config.ts 9 | ENV NODE_OPTIONS="--openssl-legacy-provider" 10 | RUN npm i && npm run build 11 | 12 | FROM scratch 13 | LABEL MAINTAINER="ylb" 14 | COPY --from=builder /app/dist /app/assets 15 | -------------------------------------------------------------------------------- /docker/latest/Dockerfile.nginx: -------------------------------------------------------------------------------- 1 | ARG VER_NGX="1.21.6-alpine" 2 | 3 | FROM --platform=$BUILDPLATFORM doocs/md:latest-assets AS assets 4 | FROM --platform=$TARGETPLATFORM nginx:${VER_NGX} 5 | LABEL MAINTAINER="ylb" 6 | COPY --from=assets /app/assets /usr/share/nginx/html 7 | -------------------------------------------------------------------------------- /docker/latest/Dockerfile.standalone: -------------------------------------------------------------------------------- 1 | ARG VER_GOLANG=1.17.6-alpine3.15 2 | ARG VER_ALPINE=3.15 3 | 4 | FROM --platform=$BUILDPLATFORM "doocs/md:latest-assets" AS assets 5 | 6 | FROM --platform=$BUILDPLATFORM "golang:$VER_GOLANG" AS gobuilder 7 | ARG TARGETARCH 8 | ARG TARGETOS 9 | COPY --from=assets /app/* /app/assets/ 10 | COPY server/main.go /app 11 | RUN apk add git bash gcc musl-dev upx 12 | WORKDIR /app 13 | ENV GOOS=$TARGETOS GOARCH=$TARGETARCH 14 | RUN go build -ldflags "-w -s" -o md main.go && \ 15 | apk add upx && \ 16 | if [ "$TARGETARCH" = "amd64" ]; then upx -9 -o md.minify md; else cp md md.minify; fi 17 | 18 | FROM --platform=$TARGETPLATFORM "alpine:$VER_ALPINE" 19 | LABEL MAINTAINER="ylb" 20 | COPY --from=gobuilder /app/md.minify /bin/md 21 | EXPOSE 80 22 | CMD ["md"] 23 | -------------------------------------------------------------------------------- /docker/latest/Dockerfile.static: -------------------------------------------------------------------------------- 1 | FROM --platform=$BUILDPLATFORM doocs/md:latest-assets AS assets 2 | 3 | # detail https://github.com/lipanski/docker-static-website/blob/master/Dockerfile 4 | FROM --platform=$TARGETPLATFORM lipanski/docker-static-website 5 | 6 | WORKDIR /home/static 7 | 8 | COPY --from=assets /app/assets /home/static 9 | 10 | EXPOSE 80 11 | 12 | CMD ["/busybox-httpd", "-f", "-v", "-p", "80", "-c", "httpd.conf"] 13 | -------------------------------------------------------------------------------- /docker/latest/patch/vite.config.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path' 2 | import process from 'node:process' 3 | 4 | import vue from '@vitejs/plugin-vue' 5 | import { visualizer } from 'rollup-plugin-visualizer' 6 | import UnoCSS from 'unocss/vite' 7 | import AutoImport from 'unplugin-auto-import/vite' 8 | import Components from 'unplugin-vue-components/vite' 9 | import { defineConfig } from 'vite' 10 | import { nodePolyfills } from 'vite-plugin-node-polyfills' 11 | import { VitePluginRadar } from 'vite-plugin-radar' 12 | import vueDevTools from 'vite-plugin-vue-devtools' 13 | 14 | export default defineConfig({ 15 | base: `/`, 16 | define: { process }, 17 | envPrefix: [`VITE_`, `CF_`], 18 | plugins: [ 19 | vue(), 20 | UnoCSS(), 21 | vueDevTools(), 22 | nodePolyfills({ 23 | include: [`path`, `util`, `timers`, `stream`, `fs`], 24 | overrides: { 25 | // Since `fs` is not supported in browsers, we can use the `memfs` package to polyfill it. 26 | // fs: 'memfs', 27 | }, 28 | }), 29 | VitePluginRadar({ 30 | analytics: { id: `G-7NZL3PZ0NK` }, 31 | }), 32 | process.env.ANALYZE === `true` 33 | && visualizer({ emitFile: true, filename: `stats.html` }), 34 | AutoImport({ 35 | imports: [`vue`, `pinia`, `@vueuse/core`], 36 | dirs: [`./src/stores`, `./src/utils/toast`, `./src/composables`], 37 | }), 38 | Components({ 39 | resolvers: [], 40 | }), 41 | ], 42 | resolve: { 43 | alias: { '@': path.resolve(__dirname, `./src`) }, 44 | }, 45 | css: { devSourcemap: true }, 46 | build: { 47 | rollupOptions: { 48 | output: { 49 | chunkFileNames: `static/js/md-[name]-[hash].js`, 50 | entryFileNames: `static/js/md-[name]-[hash].js`, 51 | assetFileNames: `static/[ext]/md-[name]-[hash].[ext]`, 52 | manualChunks(id) { 53 | if (id.includes(`node_modules`)) { 54 | if (id.includes(`katex`)) 55 | return `katex` 56 | if (id.includes(`mermaid`)) 57 | return `mermaid` 58 | if (id.includes(`cytoscape`)) 59 | return `cytoscape` 60 | if (id.includes(`highlight.js`)) 61 | return `hljs` 62 | const pkg = id 63 | .split(`node_modules/`)[1] 64 | .split(`/`)[0] 65 | .replace(`@`, `npm_`) 66 | return `vendor_${pkg}` 67 | } 68 | }, 69 | }, 70 | }, 71 | }, 72 | }) 73 | -------------------------------------------------------------------------------- /docker/latest/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | //go:embed assets 11 | var assets embed.FS 12 | 13 | func main() { 14 | mutex := http.NewServeMux() 15 | md, _ := fs.Sub(assets, "assets") 16 | mutex.Handle("/", http.FileServer(http.FS(md))) 17 | err := http.ListenAndServe(":80", mutex) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scripts/build-base-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_DIR='./docker'; 4 | REPO_NAME='doocs/md' 5 | 6 | for app_ver in $RELEASE_DIR/*; do 7 | 8 | if [ -f "$app_ver/Dockerfile.base" ]; then 9 | 10 | tag=$(echo $app_ver | cut -b 10-); 11 | echo "Build: $tag"; 12 | set -a 13 | . "$app_ver/.env" 14 | set +a 15 | 16 | echo $app_ver 17 | echo "VER_APP: $VER_APP" 18 | echo "VER_NGX: $VER_NGX" 19 | echo "VER_GOLANG: $VER_GOLANG" 20 | echo "VER_ALPINE: $VER_ALPINE" 21 | 22 | docker build --build-arg VER_APP=$VER_APP -f "$app_ver/Dockerfile.base" -t "$REPO_NAME:${VER_APP}-assets" "$app_ver" 23 | fi 24 | 25 | done -------------------------------------------------------------------------------- /scripts/build-multiarch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | RELEASE_DIR="./docker" 6 | REPO_NAME="doocs/md" 7 | PLATFORMS="linux/amd64,linux/arm64" 8 | 9 | echo "🔧 Multi-arch Docker build started..." 10 | echo "📁 Scanning directory: $RELEASE_DIR" 11 | 12 | for app_ver in "$RELEASE_DIR"/*; do 13 | [ -d "$app_ver" ] || continue 14 | 15 | tag=$(basename "$app_ver") 16 | env_file="$app_ver/.env" 17 | 18 | if [ ! -f "$env_file" ]; then 19 | echo "⚠️ Skipping $tag - missing .env file" 20 | continue 21 | fi 22 | 23 | set -a 24 | . "$env_file" 25 | set +a 26 | 27 | echo "🚀 Building images for version: $tag" 28 | echo " VER_APP: $VER_APP" 29 | echo " VER_NGX: $VER_NGX" 30 | echo " VER_GOLANG: $VER_GOLANG" 31 | echo " VER_ALPINE: $VER_ALPINE" 32 | 33 | # 构建 base 镜像 34 | if [ -f "$app_ver/Dockerfile.base" ]; then 35 | echo "📦 Building base image: $REPO_NAME:${VER_APP}-assets" 36 | docker buildx build \ 37 | --platform "$PLATFORMS" \ 38 | --build-arg VER_APP="$VER_APP" \ 39 | -f "$app_ver/Dockerfile.base" \ 40 | -t "$REPO_NAME:${VER_APP}-assets" \ 41 | --push \ 42 | "$app_ver" 43 | fi 44 | 45 | # 构建 nginx 镜像 46 | if [ -f "$app_ver/Dockerfile.nginx" ]; then 47 | echo "📦 Building nginx image: $REPO_NAME:${VER_APP}-nginx" 48 | docker buildx build \ 49 | --platform "$PLATFORMS" \ 50 | --build-arg VER_APP="$VER_APP" \ 51 | --build-arg VER_NGX="$VER_NGX" \ 52 | -f "$app_ver/Dockerfile.nginx" \ 53 | -t "$REPO_NAME:${VER_APP}-nginx" \ 54 | --push \ 55 | "$app_ver" 56 | fi 57 | 58 | # 构建 standalone 镜像 59 | if [ -f "$app_ver/Dockerfile.standalone" ]; then 60 | echo "📦 Building standalone image: $REPO_NAME:${VER_APP}" 61 | docker buildx build \ 62 | --platform "$PLATFORMS" \ 63 | --build-arg VER_APP="$VER_APP" \ 64 | --build-arg VER_NGX="$VER_NGX" \ 65 | -f "$app_ver/Dockerfile.standalone" \ 66 | -t "$REPO_NAME:${VER_APP}" \ 67 | --push \ 68 | "$app_ver" 69 | fi 70 | 71 | # 构建 static 镜像 72 | if [ -f "$app_ver/Dockerfile.static" ]; then 73 | echo "📦 Building static image: $REPO_NAME:${VER_APP}-static" 74 | docker buildx build \ 75 | --platform "$PLATFORMS" \ 76 | --build-arg VER_APP="$VER_APP" \ 77 | --build-arg VER_NGX="$VER_NGX" \ 78 | -f "$app_ver/Dockerfile.static" \ 79 | -t "$REPO_NAME:${VER_APP}-static" \ 80 | --push \ 81 | "$app_ver" 82 | fi 83 | 84 | echo "✅ Completed version: $tag" 85 | done 86 | 87 | echo "🎉 All images built and pushed successfully." 88 | -------------------------------------------------------------------------------- /scripts/build-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_DIR='./docker'; 4 | REPO_NAME='doocs/md' 5 | 6 | for app_ver in $RELEASE_DIR/*; do 7 | 8 | if [ -f "$app_ver/Dockerfile.nginx" ]; then 9 | 10 | tag=$(echo $app_ver | cut -b 10-); 11 | echo "Build: $tag"; 12 | set -a 13 | . "$app_ver/.env" 14 | set +a 15 | 16 | echo $app_ver 17 | echo "VER_APP: $VER_APP" 18 | echo "VER_NGX: $VER_NGX" 19 | echo "VER_GOLANG: $VER_GOLANG" 20 | echo "VER_ALPINE: $VER_ALPINE" 21 | 22 | docker build --build-arg VER_APP=$VER_APP --build-arg VER_NGX=$VER_NGX -f "$app_ver/Dockerfile.nginx" -t "$REPO_NAME:${VER_APP}-nginx" "$app_ver" 23 | fi 24 | 25 | done -------------------------------------------------------------------------------- /scripts/build-standalone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_DIR='./docker'; 4 | REPO_NAME='doocs/md' 5 | 6 | for app_ver in $RELEASE_DIR/*; do 7 | 8 | if [ -f "$app_ver/Dockerfile.standalone" ]; then 9 | 10 | tag=$(echo $app_ver | cut -b 10-); 11 | echo "Build: $tag"; 12 | set -a 13 | . "$app_ver/.env" 14 | set +a 15 | 16 | echo $app_ver 17 | echo "VER_APP: $VER_APP" 18 | echo "VER_NGX: $VER_NGX" 19 | echo "VER_GOLANG: $VER_GOLANG" 20 | echo "VER_ALPINE: $VER_ALPINE" 21 | 22 | docker build --build-arg VER_APP=$VER_APP --build-arg VER_NGX=$VER_NGX -f "$app_ver/Dockerfile.standalone" -t "$REPO_NAME:${VER_APP}" "$app_ver" 23 | fi 24 | 25 | done -------------------------------------------------------------------------------- /scripts/build-static.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_DIR='./docker'; 4 | REPO_NAME='doocs/md' 5 | 6 | for app_ver in $RELEASE_DIR/*; do 7 | 8 | if [ -f "$app_ver/Dockerfile.static" ]; then 9 | 10 | tag=$(echo $app_ver | cut -b 10-); 11 | echo "Build: $tag"; 12 | set -a 13 | . "$app_ver/.env" 14 | set +a 15 | 16 | echo $app_ver 17 | echo "VER_APP: $VER_APP" 18 | echo "VER_NGX: $VER_NGX" 19 | echo "VER_GOLANG: $VER_GOLANG" 20 | echo "VER_ALPINE: $VER_ALPINE" 21 | 22 | docker build --build-arg VER_APP=$VER_APP --build-arg VER_NGX=$VER_NGX -f "$app_ver/Dockerfile.static" -t "$REPO_NAME:${VER_APP}-static" "$app_ver" 23 | fi 24 | 25 | done -------------------------------------------------------------------------------- /scripts/push-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RELEASE_DIR='./docker'; 4 | REPO_NAME='doocs/md' 5 | 6 | for app_ver in $RELEASE_DIR/*; do 7 | 8 | tag=$(echo $app_ver | cut -b 10-); 9 | 10 | if [ -f "$app_ver/Dockerfile.base" ]; then 11 | # 推送构建产物,方便其他的用户和爱好者进行二次封装 12 | docker push $REPO_NAME:$tag-assets 13 | fi 14 | 15 | if [ -f "$app_ver/Dockerfile.standalone" ]; then 16 | # 推送单个二进制的镜像 17 | docker push $REPO_NAME:$tag 18 | fi 19 | 20 | if [ -f "$app_ver/Dockerfile.nginx" ]; then 21 | # 推送使用 Nginx 的镜像 22 | docker push $REPO_NAME:$tag-nginx 23 | fi 24 | 25 | if [ -f "$app_ver/Dockerfile.static" ]; then 26 | # 推送使用 lipanski/docker-static-website 的镜像 27 | docker push $REPO_NAME:$tag-static 28 | fi 29 | 30 | done --------------------------------------------------------------------------------