普通视图

发现新文章,点击刷新页面。
昨天以前首页
  • ✇新锐博客
  • Docker 搭建Github文件加速莫忘
    前言 之前是nginx反代github,但是那样要解析很多个子域名,而有些人只需要下载加速就行了 截图 开源地址 Github:https://github.com/sky22333/hub-proxy 教程 命令安装 打开SSH链接并且输入如下代码安装docker容器 docker run -d --name ghproxy -p 5000:5000 --restart always ghcr.io/sky22333/hub-proxy 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以通过网站访问了。
     

Docker 搭建Github文件加速

作者 莫忘
2025年2月10日 23:15

前言

之前是nginx反代github,但是那样要解析很多个子域名,而有些人只需要下载加速就行了

截图

图片[1]-新锐博客

开源地址

Github:https://github.com/sky22333/hub-proxy

教程

命令安装

打开SSH链接并且输入如下代码安装docker容器

docker run -d 
  --name ghproxy 
  -p 5000:5000 
  --restart always 
  ghcr.io/sky22333/hub-proxy

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

  • ✇张洪Heo
  • 如何静态化Docker容器的IP地址?构建网络实现容器固定IP张洪Heo
    这篇文章介绍了如何在使用 docker-compose 部署的环境中为容器设置固定的 IP 地址,以解决容器在重启后因 IP 自动变化导致无法上网的问题。文章首先创建了一个名为 heo_global_network 的自定义桥接网络,并将其 IP 地址段设置为 172.168.0.0/16。然后修改 docker-compose 文件,将容器连接到该外部网络并指定静态 IPv4 地址。通过这些步骤,用户可以确保容器在网络重启后保持稳定的 IP 地址,并成功实现上网功能。
     

如何静态化Docker容器的IP地址?构建网络实现容器固定IP

作者 张洪Heo
2025年2月21日 17:36
这篇文章介绍了如何在使用 docker-compose 部署的环境中为容器设置固定的 IP 地址,以解决容器在重启后因 IP 自动变化导致无法上网的问题。文章首先创建了一个名为 heo_global_network 的自定义桥接网络,并将其 IP 地址段设置为 172.168.0.0/16。然后修改 docker-compose 文件,将容器连接到该外部网络并指定静态 IPv4 地址。通过这些步骤,用户可以确保容器在网络重启后保持稳定的 IP 地址,并成功实现上网功能。
  • ✇新锐博客
  • Docker 部署文本处理工具箱莫忘
    前言 日常生活中,我们需要处理一些文本内容,这时候就需要用到一些工具了 截图 教程 1.打开SSH终端,cd到网站根目录,运行如下代码 git clone https://github.geekery.cn/https://github.com/zkeq/ai-markdown-text-toolkit.git 2.打开网站根目录并且把名为ai-markdown-text-toolkit 文件夹里的内容移到网站根目录里 3,打开名为docker-compose.yml  的文件,将其中的PASSWORD 后面的密码内容改为你自己设定的密码 4.然后去SSH终端输入以下命令启动docker docker-compose up -d 5.访问ip+3030即可访问网站
     

Docker 部署文本处理工具箱

作者 莫忘
2025年1月13日 18:53

前言

日常生活中,我们需要处理一些文本内容,这时候就需要用到一些工具了

截图

图片[1]-新锐博客

教程

1.打开SSH终端,cd到网站根目录,运行如下代码

git clone https://github.geekery.cn/https://github.com/zkeq/ai-markdown-text-toolkit.git

2.打开网站根目录并且把名为ai-markdown-text-toolkit 文件夹里的内容移到网站根目录里

3,打开名为docker-compose.yml  的文件,将其中的PASSWORD 后面的密码内容改为你自己设定的密码

4.然后去SSH终端输入以下命令启动docker

docker-compose up -d

5.访问ip+3030即可访问网站

  • ✇新锐博客
  • 适合小白的NAS系统飞牛OS安装教程莫忘
    前言 之前有一个旧电脑放在那没用,于是就想着用弄个nas系统来玩玩 教程 1.首先在可以联网的电脑上下载飞牛os的镜像包和写盘软件,写盘软件上一篇文章已经介绍了 2.打开写盘软件rufus,选择U盘(至少8G),选择镜像文件,其他文件都默认即可 3.制作启动盘结束以后插入到需要安装飞牛OS的电脑,然后在电脑启动刚开始的时候按DEL键(按照提示来,没有提示的就百度搜对应主板进入bios的方法) 4.设置启动项为U盘启动,然后就会提示你选择制作方式,选择第一个 Graphical Install ,如果有其他提示则选择第二个。 5.我在安装的时候提示了452报错,最终在我重新制作启动盘之后解决了这个问题,你们如果遇到其他情况也可以重新制作启动盘 6.进入到设置界面选择系统盘,建议是64G,而我选择的是20G,swap选择4G就差不多了 7.确认安装就可以了然后等待安装结束后确认网卡无误就能进入系统了 8.进入到指定的url地址就可以设置账户和密码了,这样就可以开启飞牛os之旅了,是不是很简单。
     

适合小白的NAS系统飞牛OS安装教程

作者 莫忘
2024年12月30日 17:01

前言

之前有一个旧电脑放在那没用,于是就想着用弄个nas系统来玩玩

教程

1.首先在可以联网的电脑上下载飞牛os的镜像包和写盘软件,写盘软件上一篇文章已经介绍了

2.打开写盘软件rufus,选择U盘(至少8G),选择镜像文件,其他文件都默认即可

image-20240826144432487

3.制作启动盘结束以后插入到需要安装飞牛OS的电脑,然后在电脑启动刚开始的时候按DEL键(按照提示来,没有提示的就百度搜对应主板进入bios的方法)

4.设置启动项为U盘启动,然后就会提示你选择制作方式,选择第一个 Graphical Install ,如果有其他提示则选择第二个。

img_v3_02eb_e43e6332-03f4-46ba-bbb7-873970e5e62g

5.我在安装的时候提示了452报错,最终在我重新制作启动盘之后解决了这个问题,你们如果遇到其他情况也可以重新制作启动盘

6.进入到设置界面选择系统盘,建议是64G,而我选择的是20G,swap选择4G就差不多了

img_v3_02e4_c9914569-6898-4134-bfa8-21094f7ca10g

7.确认安装就可以了然后等待安装结束后确认网卡无误就能进入系统了

image-20240823180036795

8.进入到指定的url地址就可以设置账户和密码了,这样就可以开启飞牛os之旅了,是不是很简单。

  • ✇新锐博客
  • Docker 搭建Mtab书签导航程序莫忘
    前言 在跨设备的时候,浏览器收藏夹可能不能同步,所以这时候就需要导航或书签程序 文档 官方地址:https://www.mtab.cc/document.html 教程 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入: itushan/mtab ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入80,服务器端口自定义。 命令安装 docker run -itd --name mtab -p 9200:80 -v /opt/mtab:/app itushan/mtab docker-compose 新建文件名为docker-compose.yaml  并且添加如下代码 #请确保您的docker-compose.yml所创建的文件夹有足够的权限,否则可能会失败, services: mysql8: image: mysql:8.0 container_name: mtab_sql #请不要修改 ports: -
     

Docker 搭建Mtab书签导航程序

作者 莫忘
2024年11月11日 10:25

前言

在跨设备的时候,浏览器收藏夹可能不能同步,所以这时候就需要导航或书签程序

文档

官方地址:https://www.mtab.cc/document.html

教程

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入: itushan/mtab ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入80,服务器端口自定义。

命令安装

 docker run -itd --name mtab -p 9200:80 -v /opt/mtab:/app itushan/mtab

docker-compose

新建文件名为docker-compose.yaml  并且添加如下代码

#请确保您的docker-compose.yml所创建的文件夹有足够的权限,否则可能会失败,
services:
  mysql8:
    image: mysql:8.0
    container_name: mtab_sql #请不要修改
    ports:
      - "9201:3306"
    volumes:
      - ./mysql8:/var/lib/mysql #如有必要请修改为其他路径,请连同mTab配置一同修改
    environment:
      MYSQL_ROOT_PASSWORD: mtab #mysql的root密码
      MYSQL_DATABASE: mtab #数据库名
      MYSQL_USER: mtab #数据库用户名
      MYSQL_PASSWORD: mtab #数据库密码
      TZ: Asia/Shanghai
      CHARACTER_SET_SERVER: utf8mb4
      COLLATION_SERVER: utf8mb4_general_ci
    restart: always
    networks:
      - my-network
  mTab:
    image: itushan/mtab
    container_name: mTabServer
    ports:
      - "9200:80"
    volumes:
      - ./mtab:/app
    environment:
      MYSQL_HOST: mtab_sql #mysql的容器名请不要修改
      MYSQL_USER: mtab #数据库用户名
      MYSQL_PORT: 3306 #数据库端口
      MYSQL_PASSWORD: mtab #数据库密码
      MYSQL_DATABASE: mtab #数据库名
      ADMIN_USER: admin # 安装后默认管理员账号 可以安装后修改
      ADMIN_PASSWORD: 123456 # 安装后默认管理员密码 可以安装后修改
    restart: always
    depends_on:
      - mysql8
    entrypoint: [ "sh", "-c", "sleep 30 && ./start.sh" ] # 延迟启动,等待mysql启动
    networks:
      - my-network
networks:
  my-network:
    driver: bridge

执行命令docker-compose up -d

  • ✇辰安博客
  • NEW 国内无法拉取Docker镜像了? Docker代理加速获取镜像 拯救你的Docker辰安
    配置 Docker 使用代理加速创建或编辑 /etc/systemd/system/docker.service.d/http-proxy.conf 配置文件(如果该目录和文件不存在,则需要创建) sudo mkdir -p /etc/systemd/system/docker.service.d sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf 在该文件中添加以下内容,替换代理地址和端口: [Service] Environment="HTTP_PROXY=socks5://username:password@ip:port" Environment="HTTPS_PROXY=socks5://username:password@ip:port" 这将设置 Docker 使用 SOCKS5 代理。 保存并关闭文件后,重新加载 systemd 并重启 Docker 服务: sudo systemctl daemon-reload sudo systemctl restart docker
     

NEW 国内无法拉取Docker镜像了? Docker代理加速获取镜像 拯救你的Docker

作者 辰安
2024年11月26日 23:32

157b2019e235051b28ea259e1790b831

配置 Docker 使用代理加速
创建或编辑 /etc/systemd/system/docker.service.d/http-proxy.conf 配置文件(如果该目录和文件不存在,则需要创建)

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

在该文件中添加以下内容,替换代理地址和端口:

[Service]
Environment="HTTP_PROXY=socks5://username:password@ip:port"
Environment="HTTPS_PROXY=socks5://username:password@ip:port"
  • 这将设置 Docker 使用 SOCKS5 代理。

  • 保存并关闭文件后,重新加载 systemd 并重启 Docker 服务:

sudo systemctl daemon-reload
sudo systemctl restart docker
  • ✇新锐博客
  • Docker 搭建思源笔记莫忘
    前言 思源笔记是一款隐私优先的个人知识管理系统,支持细粒度块级引用和 Markdown 所见即所得。 截图 教程 一键安装 宝塔面板升级9.2.0后docker应用商店找到思源笔记就可以一键安装了。 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:b3log/siyuan ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入6806,服务器端口自定义。 6.变量添加accessAuthCode=admin 命令安装 docker run -d -v /siyuan/workspace:/siyuan/workspace -p 6806:6806 -u 1000:1000 b3log/siyuan --workspace=/siyuan/workspace/ --accessAuthCode=admin Docker-Compose   新建文件名为docker-compose.yaml 并且添加如下代码 version: "3.9" services
     

Docker 搭建思源笔记

作者 莫忘
2024年9月25日 12:53

前言

思源笔记是一款隐私优先的个人知识管理系统,支持细粒度块级引用和 Markdown 所见即所得。

截图

图片[1]-新锐博客

教程

一键安装

宝塔面板升级9.2.0后docker应用商店找到思源笔记就可以一键安装了。

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入:b3log/siyuan ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入6806,服务器端口自定义。

6.变量添加accessAuthCode=admin

命令安装

docker run -d -v /siyuan/workspace:/siyuan/workspace -p 6806:6806 -u 1000:1000 b3log/siyuan --workspace=/siyuan/workspace/ --accessAuthCode=admin

Docker-Compose

 

新建文件名为docker-compose.yaml 并且添加如下代码

version: "3.9"
services:
  main:
    image: b3log/siyuan
    command: ['--workspace=/siyuan/workspace/', '--accessAuthCode=admin']
    user: '1000:1000'
    ports:
      - 6806:6806
    volumes:
      - /siyuan/workspace:/siyuan/workspace
    restart: unless-stopped
    environment:
      # A list of time zone identifiers can be found at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
      - TZ=${TimeZone}

启动容器

docker-compose up -d

设置中文

输入密码进入系统后,点击右上角有个Plugin,然后点击Manage,点击Appearance,最后在Language中选择中文即可。

结语

密码为admin

 

 

  • ✇新锐博客
  • Ollama向量模型的使用小感莫忘
    前言 因为有一台闲置的linux服务器,所以就安装了宝塔准备自己折腾一些好玩的项目。 在docker应用商店中看到了Ollama项目于是就想着部署一下。 过程 首先我以为这个是一个大语言模型,经过部署后才知道是一个向量模型。 向量模型简单理解就是知识库,当我部署好以后访问url发现只有一个ollama is running 并没有后台,研究后发现需要配合其他项目比如maxkb。 于是我就在我的maxkb中添加了这个向量模型并且使用了web服务。 填写的URL地址当然就是我网站了。可能是因为服务器配置较低,所以向量模型在处理网站内容的时候很慢。 然后就是并不是所有的文章它都会获取,而仅仅是获取首页中你已经显示的文章和分类等。 当我用命中测试想着测试一下他的准确度时发现他的响应和WordPress自带的搜索并没什么差别。 感言 首先,可能是我配置问题没有很好的利用这个向量模型。 其次,也有可能我不会使用向量模型导致体验较差。 最后,我觉得有兴趣有能力的小伙伴可以自己部署一个向量模型,作为一个知识库它是很不错的选择。  
     

Ollama向量模型的使用小感

作者 莫忘
2024年9月20日 12:58

前言

因为有一台闲置的linux服务器,所以就安装了宝塔准备自己折腾一些好玩的项目。

在docker应用商店中看到了Ollama项目于是就想着部署一下。

过程

首先我以为这个是一个大语言模型,经过部署后才知道是一个向量模型。

向量模型简单理解就是知识库,当我部署好以后访问url发现只有一个ollama is running

并没有后台,研究后发现需要配合其他项目比如maxkb。

于是我就在我的maxkb中添加了这个向量模型并且使用了web服务。

填写的URL地址当然就是我网站了。可能是因为服务器配置较低,所以向量模型在处理网站内容的时候很慢。

然后就是并不是所有的文章它都会获取,而仅仅是获取首页中你已经显示的文章和分类等。

当我用命中测试想着测试一下他的准确度时发现他的响应和WordPress自带的搜索并没什么差别。

感言

首先,可能是我配置问题没有很好的利用这个向量模型。

其次,也有可能我不会使用向量模型导致体验较差。

最后,我觉得有兴趣有能力的小伙伴可以自己部署一个向量模型,作为一个知识库它是很不错的选择。

 

  • ✇新锐博客
  • Docker自建DNS广告拦截服务-AdGuard Home莫忘
    前言 今天友链的朋友摸鱼小窝告诉我他搭建了一个DNS拦截广告的东西,于是我像他索要了教程 开源地址 Github:https://github.com/AdguardTeam/AdGuardHome 教程 命令安装 1.首先拉取镜像 docker pull adguard/adguardhome:v0.107.44 2.运行容器 原始命令 docker run --name adguardhome --restart unless-stopped -v /opt/adguardhome/workdir:/opt/adguardhome/work -v /opt/adguardhome/confdir:/opt/adguardhome/conf -p 53:53/tcp -p 53:53/udp -p 67:67/udp -p 68:68/udp -p 80:80/tcp -p 443:443/tcp -p 443:443/udp -p 3000:3000/tcp -p 853:853/tcp -p 784:784/udp
     

Docker自建DNS广告拦截服务-AdGuard Home

作者 莫忘
2024年9月8日 17:47

前言

今天友链的朋友摸鱼小窝告诉我他搭建了一个DNS拦截广告的东西,于是我像他索要了教程

开源地址

Github:https://github.com/AdguardTeam/AdGuardHome

教程

命令安装

1.首先拉取镜像

docker pull adguard/adguardhome:v0.107.44

2.运行容器

原始命令

docker run --name adguardhome
    --restart unless-stopped
    -v /opt/adguardhome/workdir:/opt/adguardhome/work
    -v /opt/adguardhome/confdir:/opt/adguardhome/conf
    -p 53:53/tcp -p 53:53/udp
    -p 67:67/udp -p 68:68/udp
    -p 80:80/tcp -p 443:443/tcp -p 443:443/udp -p 3000:3000/tcp
    -p 853:853/tcp
    -p 784:784/udp -p 853:853/udp -p 8853:8853/udp
    -p 5443:5443/tcp -p 5443:5443/udp
    -d adguard/adguardhome:v0.107.44
命令说明

-p 53:53/tcp -p 53:53/udp:普通DNS。
-p 67:67/udp-p 68:68/tcp-p 68:68/udp:如果您打算将AdGuard Home用作DHCP服务器,请添加。
-p 80:80/tcp-p 443:443/tcp-p 443:443/udp-p 3000:3000/tcp:如果您要使用AdGuard Home的管理面板,并将AdGuard Home作为HTTPS上的HTTPS/DNS服务器运行,请添加。
-p 853:853/tcp:add,如果您要将AdGuard Home作为DNS over TLS服务器运行。
-p 784:784/udp-p 853:853/udp-p 8853:8853/udp:如果您要将AdGuard Home作为QUIC服务器上的DNS运行,请添加。你只能留下其中的一两个。
-p 5443:5443/tcp-p 5443:5443/udp:如果要将AdGuard Home作为DNSCrypt服务器运行,请添加。

简化命令

docker run --name adguardhome
    --restart unless-stopped
    -v /opt/adguardhome/workdir:/opt/adguardhome/work
    -v /opt/adguardhome/confdir:/opt/adguardhome/conf
    -p 53:53/tcp -p 53:53/udp
    -p 80:80/tcp -p 3000:3000/tcp
    -d adguard/adguardhome:v0.107.44

3.查看运行状态

docker ps | grep adguardhome
docker logs adguardhome

配置教程

1. 初始化配置

1、访问网页配置界面
假设宿主机IP为 192.168.56.101 ,那么 网页配置界面 为:https://192.168.56.101:3000/

2、初始化配置
第一次登录时,AdGuard Home会引导我们对 网页管理界面 进行初始化配置。
初始化配置完成之后,网页配置界面就不能访问了。

配置数据会保存到 /opt/adguardhome/confdir/AdGuardHome.yaml 文件中。

3、访问网页管理界面
假设宿主机IP为 192.168.56.101 ,那么 网页管理界面 为:https://192.168.56.101:80/
图片[1]-新锐博客

2. AdGuard Home DNS配置

点击设置,点击DNS设置,按需配置DNS。

常用配置:

  • 上游 DNS 服务器
  • 速率限制
  • DNS 缓存配置
  • 允许的客户端
  • 不允许的客户端
  • 不允许的域名

配置数据会保存到 /opt/adguardhome/confdir/AdGuardHome.yaml 文件中。

3. 过滤器配置

3.1. DNS黑名单

点击过滤器,点击DNS黑名单。

DNS黑名单,可以阻止访问特定域名。
默认黑名单列表为AdGuard DNS filter,可选的黑名单列表还有几十个。

3.2. DNS重写

点击过滤器,点击DNS重写。

DNS重写,可以配置自定义域名解析。

3.3.自定义过滤规则

点击过滤器,点击自定义过滤规则。

自定义过滤规则,可以配置自定义域名解析,也可以阻止访问特定域名。

3.4. 客户机配置使用AdGuard Home

假设宿主机IP为 192.168.56.101 ,那么 resolv.conf 配置为:

nameserver 192.168.56.101
  • ✇新锐博客
  • 解决linux因DNS导致无法访问其他网站莫忘
    前言 在一个服务器内安装了maxkb项目,但是当我添加语言大模型的时候各种报错。 比如在安装星火大模型的时候提示校验失败,请检查参数是否正确: [Errno -3] Temporary failure in name resolutio 接下来就告诉大家怎么解决这个问题 教程 这个问题是因为DNS而出现的。 1.首先找到/etc/resolv.conf 2.将nameserver ***** 替换成如下代码 nameserver 10.8.255.1 nameserver 10.8.255.2 nameserver 114.114.114.114 3.重启网络服务:service network restart 4.重启服务器 结语 很多时候访问不了外部链接就是因为DNS的原因,所以可以尝试更换DNS来解决这类问题
     

解决linux因DNS导致无法访问其他网站

作者 莫忘
2024年9月1日 11:42

前言

在一个服务器内安装了maxkb项目,但是当我添加语言大模型的时候各种报错。

比如在安装星火大模型的时候提示校验失败,请检查参数是否正确: [Errno -3] Temporary failure in name resolutio

接下来就告诉大家怎么解决这个问题

教程

这个问题是因为DNS而出现的。

1.首先找到/etc/resolv.conf

2.将nameserver ***** 替换成如下代码

nameserver 10.8.255.1
nameserver 10.8.255.2
nameserver 114.114.114.114

3.重启网络服务:service network restart

4.重启服务器

结语

很多时候访问不了外部链接就是因为DNS的原因,所以可以尝试更换DNS来解决这类问题

  • ✇爱吃猫的鱼BLOG
  • 零基础Docker入门指南M.Talen
    1 前言Docker 是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中。这些容器可以在任何支持 Docker 的 Linux 机器上运行,无需担心环境差异带来的问题。Docker 的设计理念是“一次构建,到处运行”,这意味着一旦应用在 Docker 容器中构建完成,它就可以在任何安装了 Docker 的机器上无缝运行。特点轻量级:不需要模拟硬件,它共享宿主机的内核,因此比虚拟机更轻量。可移植性:可以在不同的环境中运行,无论是本地开发环境、测试环境还是生产环境。快速部署:可以快速启动和停止,这使得部署和扩展应用变得非常迅速。安全性:提供了良好的隔离,每个容器都是独立的,不会互相干扰。2 快速安装Docker 在不同系统的安装方式略有不同但基本相似,以下就用几个常用系统作为演示。2.1 Ubuntu使用 Ubuntu 22.04 LTS,理论上各版本可通用更新系统软件包索引,如果较慢可以更换镜像源1sudo apt update安装必要的依赖包1sudo apt install apt-transport-https ca-certificates
     

零基础Docker入门指南

作者 M.Talen
2024年6月13日 22:54

1 前言

Docker 是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器中。这些容器可以在任何支持 Docker 的 Linux 机器上运行,无需担心环境差异带来的问题。Docker 的设计理念是“一次构建,到处运行”,这意味着一旦应用在 Docker 容器中构建完成,它就可以在任何安装了 Docker 的机器上无缝运行。

特点

  • 轻量级:不需要模拟硬件,它共享宿主机的内核,因此比虚拟机更轻量。
  • 可移植性:可以在不同的环境中运行,无论是本地开发环境、测试环境还是生产环境。
  • 快速部署:可以快速启动和停止,这使得部署和扩展应用变得非常迅速。
  • 安全性:提供了良好的隔离,每个容器都是独立的,不会互相干扰。

2 快速安装

Docker 在不同系统的安装方式略有不同但基本相似,以下就用几个常用系统作为演示。

2.1 Ubuntu

使用 Ubuntu 22.04 LTS,理论上各版本可通用

更新系统软件包索引,如果较慢可以更换镜像源

1
sudo apt update

安装必要的依赖包

1
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

添加阿里云 GPG 密钥

1
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

添加阿里云 APT 软件源,在国内不推荐使用官方源,如需使用官方源请添加官方 GPG 密钥

1
2
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 过程需要使用一次回车键

更新软件包索引并安装 Docker Engine

1
2
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

启动Docker服务

1
sudo systemctl start docker

验证安装是否成功

1
2
3
docker --version
# 出现版本号即为安装成功
# Docker version 26.1.3, build b72abbb

2.2 Debian

使用 Debian 12.5,理论上各版本可通用

更新系统软件包索引,如果较慢可以更换镜像源

1
sudo apt-get update

安装必要的依赖包

1
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common

添加阿里云 GPG 密钥

1
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

添加阿里云 APT 软件源,在国内不推荐使用官方源,如需使用官方源请添加官方 GPG 密钥

1
2
echo "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 过程需要使用一次回车键

更新软件包索引并安装 Docker Engine

1
2
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io

启动Docker服务

1
sudo systemctl start docker

验证安装是否成功

1
2
3
docker --version
# 出现版本号即为安装成功
# Docker version 26.1.3, build b72abbb

2.3 CentOS

使用 CentOS Stream 9,理论上 CentOS 7.x 也可以使用

更新系统软件包索引,如果较慢可以更换镜像源

1
sudo yum update -y

安装必要的依赖包

1
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

从国内服务器上下载存储库,在国内不推荐使用官方库

1
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 Docker Engine

1
sudo yum install -y docker-ce docker-ce-cli containerd.io

启动Docker服务

1
sudo systemctl start docker

验证安装是否成功

1
2
3
docker --version
# 出现版本号即为安装成功
# Docker version 26.1.3, build b72abbb

3 常用命令

镜像管理命令

  • docker pull:从Docker Hub或其他仓库拉取镜像
  • docker images:列出本地所有镜像
  • docker rmi:删除指定的镜像
  • docker build:从 Dockerfile 构建新的镜像
  • docker commit:将容器保存为新的镜像
  • docker tag:给镜像打标签
  • docker push:将镜像推送到仓库
  • docker search:在 Docker Hub 上搜索镜像

容器管理命令

  • docker run:创建并运行一个新的容器
  • docker start:启动一个已停止的容器
  • docker stop:停止一个正在运行的容器
  • docker restart:重启一个容器
  • docker pause:暂停一个或多个容器的所有进程
  • docker unpause:恢复一个或多个容器的所有进程
  • docker kill:强制停止一个或多个容器
  • docker rm:删除一个或多个容器
  • docker ps:列出当前运行的容器
  • docker ps -a:列出所有容器,包括已停止的
  • docker inspect:查看容器的详细信息
  • docker exec:在容器内运行命令
  • docker logs:获取容器的日志
  • docker cp:在容器与宿主机间复制文件

网络管理命令

  • docker network ls:列出所有网络
  • docker network create:创建新网络
  • docker network connect:连接容器到网络
  • docker network disconnect:从网络断开容器
  • docker network rm:删除网络。

卷管理命令

  • docker volume ls:列出所有卷
  • docker volume create:创建新卷
  • docker volume inspect:查看卷的详细信息
  • docker volume rm:删除卷

系统信息命令

  • docker version:显示 Docker 版本信息
  • docker info:显示 Docker 系统信息

4 使用示例

4.1 Nginx

拉取 Nginx 镜像

1
docker pull nginx

运行 Nginx 容器

1
docker run --name nginx-test -p 8080:80 -d nginx
  • --name nginx-test:设置容器名称
  • -p 8080:80: 映射容器服务的 80 端口到宿主机的 8080 端口
  • -d nginx: 设置容器在在后台一直运行

若在浏览器成功访问 IP:8080 即为安装成功,注意需要放行对应端口

image-20240605155040664

3.2 MySQL

拉取 MySQL 镜像

1
docker pull mysql

运行 MySQL 容器

1
docker run -it --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
  • -it:启动一个交互式 shell
  • -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口
  • -e MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码
  • -d mysql: 设置容器在在后台一直运行

使用 Navicat Premium 工具测试是否安装成功,注意需要放行对应端口

image-20240605175605003

5 Docker Compose

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose 可以使用 YML 文件来配置应用程序需要的所有服务,然后使用一个命令就可以从 YML 文件配置中创建并启动所有服务。

5.1 安装

下载 Docker Compose 二进制文件

1
sudo curl -L "https://githubfast.com/docker/compose/releases/download/v2.27.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

赋予 Docker Compose 执行权限

1
sudo chmod +x /usr/local/bin/docker-compose

验证安装是否成功

1
2
3
docker-compose --version
# 出现版本号即为安装成功
# Docker Compose version v2.27.1

5.2 使用示例

创建并进入一个测试目录

1
mkdir composetest & cd composetest

创建并编辑 docker-compose.yml 文件

1
vim docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# docker-compose.yml
services: # 在这个配置文件中,定义了两个服务 nc(Nextcloud) 和 db(PostgreSQL)
nc: # Nextcloud
image: nextcloud:apache # 指定容器使用的镜像为 nextcloud:apache
environment: # 设置环境变量,包括数据库的连接信息
- POSTGRES_HOST=db # 指定数据库服务的名称
- POSTGRES_PASSWORD=nextcloud # 数据库密码
- POSTGRES_DB=nextcloud # 数据库名
- POSTGRES_USER=nextcloud # 数据库用户名
ports: # 映射容器服务的 80 端口到宿主机的 80 端口
- 80:80
restart: always # 指定容器总是重启
volumes: # 挂载卷 nc_data 到容器内 /var/www/html 目录,用于持久化 Nextcloud 的数据
- nc_data:/var/www/html
db: # PostgreSQL
image: postgres:alpine # 指定容器使用的镜像为 postgres:alpine
environment: # 设置环境变量,包括数据库的配置信息
- POSTGRES_PASSWORD=nextcloud # 数据库密码
- POSTGRES_DB=nextcloud # 数据库名
- POSTGRES_USER=nextcloud # 数据库用户名
restart: always # 指定容器总是重启
volumes: # 挂载卷 db_data 到容器内 /var/lib/postgresql/data 目录,用于持久化数据库的数据
- db_data:/var/lib/postgresql/data
expose: # 暴露容器的5432端口
- 5432
volumes: # 卷
db_data: # 定义了一个名为 db_data 的卷,用于存储数据库的数据
nc_data: # 定义了一个名为 nc_data 的卷,用于存储 Nextcloud 的数据

构建应用并在后台执行该服务

1
docker-compose up -d

等待构建完成后,在浏览器访问 IP:80 成功出现下图即为成功,注意需要放行对应端口

image-20240605182752361

6 写在最后

Docker 是一个强大的工具,它简化了应用的部署和管理过程。无论是开发者还是系统管理员,学习 Docker 都将大大提升工作效率。本文侧重于如何安装 Docker,如需深入学习推荐使用官方文档:https://docs.docker.com/guides/

  • ✇新锐博客
  • 一个docker项目导致服务器爆满莫忘
    前言 最近在群里聊天的时候,有人在群里发了一个自己搭建的docker项目-maxkb。 这是一个知识库和大语言模型结合的项目,所以我就想自己搭建一个玩玩。 当然这篇文章不是介绍如何搭建此项目,不过搭建也很简单,拉取1panel/maxkb ,端口号为8080就可以了。 过程 因为当前服务器是网站的服务器,所以我首先测试的时候没有在当前服务器部署,而是在香港的那台服务器部署的。 那台服务器就搭建了一个网站,而且还没有什么访问量,所以CPU和内存都很低,这很关键,后面会说到。 当搭建好以后我就准备在当前服务器搭建了,一开始没注意,后来才发现这个项目高达2.7G。 后来加了项目的微信群才知道它们将向量模型添加到本地了,你可以直接调用本地模型。 当然我的初衷只是想调用大语言模型而不是使用知识库,但是当我在容器添加此项目之后,服务器点任何东西都没有反应了。 紧接着我访问网站都很卡,于是就去后台重启服务器,但是重启了没一会又是爆满,甚至SSH连接都无法连接。 重启了几次等待许久以后终于正常点了,就查找原因,发现刚刚部署的docker项目停止了。 我就纳闷了,为何这个项目停止了服务器就正常了,我就去
     

一个docker项目导致服务器爆满

作者 莫忘
2024年8月18日 00:26

前言

最近在群里聊天的时候,有人在群里发了一个自己搭建的docker项目-maxkb。

这是一个知识库和大语言模型结合的项目,所以我就想自己搭建一个玩玩。

当然这篇文章不是介绍如何搭建此项目,不过搭建也很简单,拉取1panel/maxkb ,端口号为8080就可以了。

过程

因为当前服务器是网站的服务器,所以我首先测试的时候没有在当前服务器部署,而是在香港的那台服务器部署的。

那台服务器就搭建了一个网站,而且还没有什么访问量,所以CPU和内存都很低,这很关键,后面会说到。

当搭建好以后我就准备在当前服务器搭建了,一开始没注意,后来才发现这个项目高达2.7G。

后来加了项目的微信群才知道它们将向量模型添加到本地了,你可以直接调用本地模型。

当然我的初衷只是想调用大语言模型而不是使用知识库,但是当我在容器添加此项目之后,服务器点任何东西都没有反应了。

紧接着我访问网站都很卡,于是就去后台重启服务器,但是重启了没一会又是爆满,甚至SSH连接都无法连接。

重启了几次等待许久以后终于正常点了,就查找原因,发现刚刚部署的docker项目停止了。

我就纳闷了,为何这个项目停止了服务器就正常了,我就去提交了工单并且询问了项目群里的人都没有给出很好的答案。

最后发现香港那台服务器的内存占用挺高的,本来2G内存占用了接近1.5G,而我这台服务器有其他项目和网站,再加上这个项目内存就不足了。

内存不够虚拟内存就需要登场了,估计是因为这个原因所以磁盘会一直以每秒200mb进行读取(个人猜测)。

结语

废话这么多只是作为一个记录,也提示各位和我一样用着小水管国内服务器的朋友,最好不要用这种很大占用的项目。

最后,实名羡慕拥有高配置服务器的大佬!!!

  • ✇新锐博客
  • 彩虹DNS - 实现一个平台管理多平台域名解析莫忘
    前言 因为域名价格的问题,有些人和我一样在华为云和阿里云都有域名,那如何管理它们呢。 简介 聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析,目前已支持的域名平台有: 阿里云 腾讯云 华为云 西部数码 DNSLA CloudFlare 功能特性 多用户管理,可为每个用户可分配不同的域名解析权限 提供API接口,可获取域名单独的登录链接,方便各种IDC系统对接 容灾切换功能,支持ping、tcp、http(s)检测协议并自动暂停/修改域名解析,并支持邮件、微信公众号通知 CF优选IP功能,支持获取最新的Cloudflare优选IP,并自动更新到解析记录 部署方法 从Release页面下载安装包 运行环境要求PHP7.4+,MySQL5.6+ 设置网站运行目录为public 设置伪静态为ThinkPHP 如果是下载的Source code包,还需Composer安装依赖(Release页面下载的安装包不需要) composer install --no-dev 访问网站,会自动跳转到安装页面,根据提示安装完成 访问首页登录控制面板 伪静态规则 Ngi
     

彩虹DNS - 实现一个平台管理多平台域名解析

作者 莫忘
2024年8月13日 13:15

前言

因为域名价格的问题,有些人和我一样在华为云和阿里云都有域名,那如何管理它们呢。

简介

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析,目前已支持的域名平台有:

  • 阿里云
  • 腾讯云
  • 华为云
  • 西部数码
  • DNSLA
  • CloudFlare

功能特性

  • 多用户管理,可为每个用户可分配不同的域名解析权限
  • 提供API接口,可获取域名单独的登录链接,方便各种IDC系统对接
  • 容灾切换功能,支持ping、tcp、http(s)检测协议并自动暂停/修改域名解析,并支持邮件、微信公众号通知
  • CF优选IP功能,支持获取最新的Cloudflare优选IP,并自动更新到解析记录

部署方法

Release页面下载安装包

运行环境要求PHP7.4+,MySQL5.6+

设置网站运行目录为public

设置伪静态为ThinkPHP

如果是下载的Source code包,还需Composer安装依赖(Release页面下载的安装包不需要)

composer install --no-dev

访问网站,会自动跳转到安装页面,根据提示安装完成

访问首页登录控制面板

伪静态规则

Nginx

location / {
	if (!-e $request_filename){
		rewrite  ^(.*)$  /index.php?s=$1  last;   break;
	}
}

Apache

<IfModule mod_rewrite.c>
  Options +FollowSymlinks -Multiviews
  RewriteEngine On

  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule

docker部署

首先需要安装Docker,然后执行以下命令拉取镜像并启动(启动后监听8081端口):

docker run --name dnsmgr -dit -p 8081:80 -v /var/dnsmgr:/app/www netcccyun/dnsmgr

访问并安装好后如果容灾切换未自动启动,重启容器即可:

docker restart dnsmgr
  • ✇新锐博客
  • docker部署方式的重要性莫忘
    前言 在我们部署项目的时候,docker往往成为首选,因为docker能够一键部署从而省去部署环境的繁琐。 但是部署的方式就有些区别。 方式 1.应用商店 宝塔的docker拥有很多项目的应用商店,这大大降低了新手部署docker项目的难度 2.镜像拉取 我们可以通过yidadaa/chatgpt-web-next 这样的命令来拉取镜像,然后再设置端口来部署项目。 3.yaml文件部署 我们还可以在文件中新建一个yaml文件,并且填入相应的参数等然后通过docker命令来部署。 总结 综上所述,第一种方式无疑是最简单的,非常适合新手,而yaml的方式对于新手来说就不是那么友好了。 碎语 我是一个喜欢瞎倒腾的人,所以今天在部署alist云盘的时候,就手贱的去动了一下umami的设置。虽然能够成功启动,但是会一直停止并且重启。 因为本人是个新手,所以一开始选择的方式是第一种应用商店部署,但是由于众所周知的原因docker一直拉取失败。 于是我就更换了yaml方式部署,这次将umami弄崩了以后我还以为要重新搞并且数据会丢失。 但是因为我使用的事yaml部署的方式,所以数据都保存在了我存放y
     

docker部署方式的重要性

作者 莫忘
2024年8月4日 17:54

前言

在我们部署项目的时候,docker往往成为首选,因为docker能够一键部署从而省去部署环境的繁琐。

但是部署的方式就有些区别。

方式

1.应用商店

宝塔的docker拥有很多项目的应用商店,这大大降低了新手部署docker项目的难度

2.镜像拉取

我们可以通过yidadaa/chatgpt-web-next 这样的命令来拉取镜像,然后再设置端口来部署项目。

3.yaml文件部署

我们还可以在文件中新建一个yaml文件,并且填入相应的参数等然后通过docker命令来部署。

总结

综上所述,第一种方式无疑是最简单的,非常适合新手,而yaml的方式对于新手来说就不是那么友好了。

碎语

我是一个喜欢瞎倒腾的人,所以今天在部署alist云盘的时候,就手贱的去动了一下umami的设置。虽然能够成功启动,但是会一直停止并且重启。

因为本人是个新手,所以一开始选择的方式是第一种应用商店部署,但是由于众所周知的原因docker一直拉取失败。

于是我就更换了yaml方式部署,这次将umami弄崩了以后我还以为要重新搞并且数据会丢失。

但是因为我使用的事yaml部署的方式,所以数据都保存在了我存放yaml文件的地方,只需要我重新运行一下docker命令完成一下部署就行了。

结语

所以能够使用yaml部署的项目就尽量使用yaml来部署。

  • ✇新锐博客
  • Docker 搭建全平台文件传输Snapdrop莫忘
    前言 Snapdrop是一个跨平台跨设备文件传输工具,能够帮助我们实现Windows、Mac、Android、iOS设备之间进行文件互传。 截图 教程 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:linuxserver/snapdrop ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入80和443,服务器端口自定义。 命令安装 docker run --name snapdrop -p 80:80 -p 443:443 -d linuxserver/snapdrop 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以通过网站访问了。
     

Docker 搭建全平台文件传输Snapdrop

作者 莫忘
2024年7月25日 00:18

前言

Snapdrop是一个跨平台跨设备文件传输工具,能够帮助我们实现Windows、Mac、Android、iOS设备之间进行文件互传。

截图

图片[1]-新锐博客

教程

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入:linuxserver/snapdrop ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入80和443,服务器端口自定义。

命令安装

docker run --name snapdrop -p 80:80 -p 443:443 -d linuxserver/snapdrop

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

  • ✇新锐博客
  • Docker 部署消息推送服务莫忘
    前言 搭建专属于你的消息推送服务,支持多种消息推送方式,支持 Markdown,仅单可执行文件,开箱即用。 简介 多种消息推送方式: 邮件消息, 微信测试号, 企业微信应用号, 企业微信群机器人 飞书群机器人, 钉钉群机器人, Bark App, WebSocket 客户端(官方客户端,接入文档), Telegram 机器人, Discord 群机器人, 多种用户登录注册方式: 邮箱登录注册以及通过邮箱进行密码重置。 GitHub 开放授权。 微信公众号授权(需要额外部署 WeChat Server)。 支持 Markdown。 支持用户管理。 Cloudflare Turnstile 用户校验。 支持在线发布公告,设置关于界面以及页脚。 支持在 Web 端管理发送的消息,支持自动刷新。 演示 官方部署站 https://msgpusher.com 现已上线,当前开放注册,欢迎使用。 教程 命令安装 docker run -d --restart always --name message-pusher -p 3000:3000 -e TZ=Asia/Shanghai
     

Docker 部署消息推送服务

作者 莫忘
2024年7月10日 09:18

前言

搭建专属于你的消息推送服务,支持多种消息推送方式,支持 Markdown,仅单可执行文件,开箱即用。

简介

  1. 多种消息推送方式:
    • 邮件消息,
    • 微信测试号,
    • 企业微信应用号,
    • 企业微信群机器人
    • 飞书群机器人,
    • 钉钉群机器人,
    • Bark App,
    • WebSocket 客户端(官方客户端接入文档),
    • Telegram 机器人,
    • Discord 群机器人,
  2. 多种用户登录注册方式:
  3. 支持 Markdown。
  4. 支持用户管理。
  5. Cloudflare Turnstile 用户校验。
  6. 支持在线发布公告,设置关于界面以及页脚。
  7. 支持在 Web 端管理发送的消息,支持自动刷新。

演示

官方部署站 https://msgpusher.com 现已上线,当前开放注册,欢迎使用。

教程

命令安装

docker run -d --restart always --name message-pusher -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/message-pusher:/data justsong/message-pusher

其中3000为访问端口。

更新镜像

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR

注意

如果需要使用 WebSocket 客户端推送功能,则 Nginx 的配置文件中 proxy_read_timeout  和 proxy_send_timeout  务必设置超过 1 分钟。

推荐设置:

proxy_read_timeout 300s; 
proxy_send_timeout 300s; 

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

 

  • ✇新锐博客
  • 使用Cloudflare搭建docker镜像站莫忘
    前言 之前介绍的docker镜像站都是别人的不是自己的,于是就可以用cloudflare搭建属于自己的docker镜像站。 教程 1.首先要注册一个Cloudflare账号。 2.Cloudflare账号下域名的一级域名,不会的自行百度如何修改DNS记录以便托管到cloudflare。 3.注意 Worker 每天每免费账号有次数限制,为10万次。每分钟为1000次。 4.本教程来源于Github开源项目cf-workers-docker 方法一 1.登录cloudflare官网,选择workers和pages,创建workers 2.编辑worker.js,将如下代码放到其中并且在右上角选择部署。 // _worker.js // Docker镜像仓库主机地址 let hub_host = 'registry-1.docker.io' // Docker认证服务器地址 const auth_url = 'https://auth.docker.io' // 自定义的工作服务器地址 let workers_url = 'https://你的域名' // 根据主机名选择对应的上游地址
     

使用Cloudflare搭建docker镜像站

作者 莫忘
2024年6月21日 01:33

前言

之前介绍的docker镜像站都是别人的不是自己的,于是就可以用cloudflare搭建属于自己的docker镜像站。

教程

1.首先要注册一个Cloudflare账号。

2.Cloudflare账号下域名的一级域名,不会的自行百度如何修改DNS记录以便托管到cloudflare。

3.注意 Worker 每天每免费账号有次数限制,为10万次。每分钟为1000次。

4.本教程来源于Github开源项目cf-workers-docker

方法一

1.登录cloudflare官网,选择workers和pages,创建workers

2.编辑worker.js,将如下代码放到其中并且在右上角选择部署。

// _worker.js

// Docker镜像仓库主机地址
let hub_host = 'registry-1.docker.io'
// Docker认证服务器地址
const auth_url = 'https://auth.docker.io'
// 自定义的工作服务器地址
let workers_url = 'https://你的域名'

// 根据主机名选择对应的上游地址
function routeByHosts(host) {
		// 定义路由表
	const routes = {
		// 生产环境
		"quay": "quay.io",
		"gcr": "gcr.io",
		"k8s-gcr": "k8s.gcr.io",
		"k8s": "registry.k8s.io",
		"ghcr": "ghcr.io",
		"cloudsmith": "docker.cloudsmith.io",
		
		// 测试环境
		"test": "registry-1.docker.io",
	};

	if (host in routes) return [ routes[host], false ];
	else return [ hub_host, true ];
}

/** @type {RequestInit} */
const PREFLIGHT_INIT = {
	// 预检请求配置
	headers: new Headers({
		'access-control-allow-origin': '*', // 允许所有来源
		'access-control-allow-methods': 'GET,POST,PUT,PATCH,TRACE,DELETE,HEAD,OPTIONS', // 允许的HTTP方法
		'access-control-max-age': '1728000', // 预检请求的缓存时间
	}),
}

/**
 * 构造响应
 * @param {any} body 响应体
 * @param {number} status 响应状态码
 * @param {Object<string, string>} headers 响应头
 */
function makeRes(body, status = 200, headers = {}) {
	headers['access-control-allow-origin'] = '*' // 允许所有来源
	return new Response(body, { status, headers }) // 返回新构造的响应
}

/**
 * 构造新的URL对象
 * @param {string} urlStr URL字符串
 */
function newUrl(urlStr) {
	try {
		return new URL(urlStr) // 尝试构造新的URL对象
	} catch (err) {
		return null // 构造失败返回null
	}
}

function isUUID(uuid) {
	// 定义一个正则表达式来匹配 UUID 格式
	const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
	
	// 使用正则表达式测试 UUID 字符串
	return uuidRegex.test(uuid);
}

async function nginx() {
	const text = `
	<!DOCTYPE html>
	<html>
	<head>
	<title>Welcome to nginx!</title>
	<style>
		body {
			width: 35em;
			margin: 0 auto;
			font-family: Tahoma, Verdana, Arial, sans-serif;
		}
	</style>
	</head>
	<body>
	<h1>Welcome to nginx!</h1>
	<p>If you see this page, the nginx web server is successfully installed and
	working. Further configuration is required.</p>
	
	<p>For online documentation and support please refer to
	<a href="https://nginx.org/">nginx.org</a>.<br/>
	Commercial support is available at
	<a href="https://nginx.com/">nginx.com</a>.</p>
	
	<p><em>Thank you for using nginx.</em></p>
	</body>
	</html>
	`
	return text ;
}

export default {
	async fetch(request, env, ctx) {
		const getReqHeader = (key) => request.headers.get(key); // 获取请求头

		let url = new URL(request.url); // 解析请求URL
		workers_url = `https://${url.hostname}`;
		const pathname = url.pathname;
		const hostname = url.searchParams.get('hubhost') || url.hostname; 
		const hostTop = hostname.split('.')[0];// 获取主机名的第一部分
		const checkHost = routeByHosts(hostTop);
		hub_host = checkHost[0]; // 获取上游地址
		const fakePage = checkHost[1];
		console.log(`域名头部: ${hostTop}n反代地址: ${hub_host}n伪装首页: ${fakePage}`);
		const isUuid = isUUID(pathname.split('/')[1].split('/')[0]);
		
		const conditions = [
			isUuid,
			pathname.includes('/_'),
			pathname.includes('/r'),
			pathname.includes('/v2/user'),
			pathname.includes('/v2/orgs'),
			pathname.includes('/v2/_catalog'),
			pathname.includes('/v2/categories'),
			pathname.includes('/v2/feature-flags'),
			pathname.includes('search'),
			pathname.includes('source'),
			pathname === '/',
			pathname === '/favicon.ico',
			pathname === '/auth/profile',
		];

		if (conditions.some(condition => condition) && (fakePage === true || hostTop == 'docker')) {
			if (env.URL302){
				return Response.redirect(env.URL302, 302);
			} else if (env.URL){
				if (env.URL.toLowerCase() == 'nginx'){
					//首页改成一个nginx伪装页
					return new Response(await nginx(), {
						headers: {
							'Content-Type': 'text/html; charset=UTF-8',
						},
					});
				} else return fetch(new Request(env.URL, request));
			}
			
			const newUrl = new URL("https://registry.hub.docker.com" + pathname + url.search);

			// 复制原始请求的标头
			const headers = new Headers(request.headers);

			// 确保 Host 头部被替换为 hub.docker.com
			headers.set('Host', 'registry.hub.docker.com');

			const newRequest = new Request(newUrl, {
					method: request.method,
					headers: headers,
					body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.blob() : null,
					redirect: 'follow'
			});

			return fetch(newRequest);
		}

		// 修改包含 %2F 和 %3A 的请求
		if (!/%2F/.test(url.search) && /%3A/.test(url.toString())) {
			let modifiedUrl = url.toString().replace(/%3A(?=.*?&)/, '%3Alibrary%2F');
			url = new URL(modifiedUrl);
			console.log(`handle_url: ${url}`)
		}

		// 处理token请求
		if (url.pathname.includes('/token')) {
			let token_parameter = {
				headers: {
					'Host': 'auth.docker.io',
					'User-Agent': getReqHeader("User-Agent"),
					'Accept': getReqHeader("Accept"),
					'Accept-Language': getReqHeader("Accept-Language"),
					'Accept-Encoding': getReqHeader("Accept-Encoding"),
					'Connection': 'keep-alive',
					'Cache-Control': 'max-age=0'
				}
			};
			let token_url = auth_url + url.pathname + url.search
			return fetch(new Request(token_url, request), token_parameter)
		}

		// 修改 /v2/ 请求路径
		if (/^/v2/[^/]+/[^/]+/[^/]+$/.test(url.pathname) && !/^/v2/library/.test(url.pathname)) {
			url.pathname = url.pathname.replace(//v2//, '/v2/library/');
			console.log(`modified_url: ${url.pathname}`)
		}

		// 更改请求的主机名
		url.hostname = hub_host;

		// 构造请求参数
		let parameter = {
			headers: {
				'Host': hub_host,
				'User-Agent': getReqHeader("User-Agent"),
				'Accept': getReqHeader("Accept"),
				'Accept-Language': getReqHeader("Accept-Language"),
				'Accept-Encoding': getReqHeader("Accept-Encoding"),
				'Connection': 'keep-alive',
				'Cache-Control': 'max-age=0'
			},
			cacheTtl: 3600 // 缓存时间
		};

		// 添加Authorization头
		if (request.headers.has("Authorization")) {
			parameter.headers.Authorization = getReqHeader("Authorization");
		}

		// 发起请求并处理响应
		let original_response = await fetch(new Request(url, request), parameter)
		let original_response_clone = original_response.clone();
		let original_text = original_response_clone.body;
		let response_headers = original_response.headers;
		let new_response_headers = new Headers(response_headers);
		let status = original_response.status;

		// 修改 Www-Authenticate 头
		if (new_response_headers.get("Www-Authenticate")) {
			let auth = new_response_headers.get("Www-Authenticate");
			let re = new RegExp(auth_url, 'g');
			new_response_headers.set("Www-Authenticate", response_headers.get("Www-Authenticate").replace(re, workers_url));
		}

		// 处理重定向
		if (new_response_headers.get("Location")) {
			return httpHandler(request, new_response_headers.get("Location"))
		}

		// 返回修改后的响应
		let response = new Response(original_text, {
			status,
			headers: new_response_headers
		})
		return response;
	}
};

/**
 * 处理HTTP请求
 * @param {Request} req 请求对象
 * @param {string} pathname 请求路径
 */
function httpHandler(req, pathname) {
	const reqHdrRaw = req.headers

	// 处理预检请求
	if (req.method === 'OPTIONS' &&
		reqHdrRaw.has('access-control-request-headers')
	) {
		return new Response(null, PREFLIGHT_INIT)
	}

	let rawLen = ''

	const reqHdrNew = new Headers(reqHdrRaw)

	const refer = reqHdrNew.get('referer')

	let urlStr = pathname

	const urlObj = newUrl(urlStr)

	/** @type {RequestInit} */
	const reqInit = {
		method: req.method,
		headers: reqHdrNew,
		redirect: 'follow',
		body: req.body
	}
	return proxy(urlObj, reqInit, rawLen)
}

/**
 * 代理请求
 * @param {URL} urlObj URL对象
 * @param {RequestInit} reqInit 请求初始化对象
 * @param {string} rawLen 原始长度
 */
async function proxy(urlObj, reqInit, rawLen) {
	const res = await fetch(urlObj.href, reqInit)
	const resHdrOld = res.headers
	const resHdrNew = new Headers(resHdrOld)

	// 验证长度
	if (rawLen) {
		const newLen = resHdrOld.get('content-length') || ''
		const badLen = (rawLen !== newLen)

		if (badLen) {
			return makeRes(res.body, 400, {
				'--error': `bad len: ${newLen}, except: ${rawLen}`,
				'access-control-expose-headers': '--error',
			})
		}
	}
	const status = res.status
	resHdrNew.set('access-control-expose-headers', '*')
	resHdrNew.set('access-control-allow-origin', '*')
	resHdrNew.set('Cache-Control', 'max-age=1500')

	// 删除不必要的头
	resHdrNew.delete('content-security-policy')
	resHdrNew.delete('content-security-policy-report-only')
	resHdrNew.delete('clear-site-data')

	return new Response(res.body, {
		status,
		headers: resHdrNew
	})
}

3.进入网站选择workers路由

4.填写需要的子域名比如hub.xxxx.com和部署完成的workers项目

5.进入网站的DNS解析,添加hub.xxxx.com的A解析,可以指向8.8.8.8

方法二

1.访问cf-workers-docker,fork项目到自己仓库。

2.登录cloudflare找到workers和pages,选择pages关联github。

3.选择fork的cf-workers-docke项目,一键创建pages。

4.进入项目设置找到自定义域,填写比如hub.xxxx.com域名,最后会自动cname解析到生成项目地址。

设置

方式一

修改文件 /etc/docker/daemon.json(如果不存在则创建)

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://hub.xxxx.com"]  # 请替换为您自己的Worker自定义域名
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

方式二

命令拉取镜像,比如

docker pull hub.xxxx.com/yidadaa/chatgpt-next-web

结语

自此搭建完成,因为有访问量的限制,所以最好是自己用不要外放出来。

  • ✇新锐博客
  • Docker 部署Moments开启RSS订阅之旅莫忘
    前言 今天给大家分享一个不错的开源项目Moments。它通过整合各种订阅源,如 RSS 和 Atom,将你感兴趣的博客转化为一个个人朋友圈。 项目地址 github:https://github.com/Drizzle365/Moments 命令安装 docker run -d --name moments -p 3000:80 drizzle2001/moments 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:drizzle2001/moments,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入80,服务器端口自定义。 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以通过网站访问了。 修正时区 ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
     

Docker 部署Moments开启RSS订阅之旅

作者 莫忘
2024年6月9日 15:17

前言

今天给大家分享一个不错的开源项目Moments。它通过整合各种订阅源,如 RSS 和 Atom,将你感兴趣的博客转化为一个个人朋友圈。

项目地址

github:https://github.com/Drizzle365/Moments

命令安装

docker run -d 
--name moments 
-p 3000:80 
drizzle2001/moments

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。
2.找到镜像,点击从仓库中拉取。
3.选择官方镜像库,输入:drizzle2001/moments,接着等待获取成功。
4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。
5.容器端口输入80,服务器端口自定义。

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

修正时区

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  • ✇新锐博客
  • Docker拉取镜像慢的解决方法莫忘
    前言 今天不知道怎么回事,在国内服务器拉取docker的镜像就会非常慢,可能和docker官网有关系,毕竟是在国外。 之前也说过替换docker国内源,但是尝试了一下发现还是不行,于是有了个新办法。 教程 首先感谢SuperManito在github上提供的一种方法。 1.将如下代码保存到网站目录下的以sh为后缀的文件中,可以新建一个文件,比如ceshi.sh #!/bin/bash ## Author: SuperManito ## Modified: 2024-01-31 ## License: MIT ## GitHub: https://github.com/SuperManito/LinuxMirrors ## Website: https://linuxmirrors.cn ## Docker Registry 镜像仓库列表 # 格式:"软件源名称@软件源地址" mirror_list_registry=( "上海交通大学@docker.mirrors.sjtug.sjtu.edu.cn" "网易@hub-mirror.c.163.com" "腾讯
     

Docker拉取镜像慢的解决方法

作者 莫忘
2024年6月6日 21:42

前言

今天不知道怎么回事,在国内服务器拉取docker的镜像就会非常慢,可能和docker官网有关系,毕竟是在国外。

之前也说过替换docker国内源,但是尝试了一下发现还是不行,于是有了个新办法。

教程

首先感谢SuperManito在github上提供的一种方法。

1.将如下代码保存到网站目录下的以sh为后缀的文件中,可以新建一个文件,比如ceshi.sh

#!/bin/bash
## Author: SuperManito
## Modified: 2024-01-31
## License: MIT
## GitHub: https://github.com/SuperManito/LinuxMirrors
## Website: https://linuxmirrors.cn

## Docker Registry 镜像仓库列表
# 格式:"软件源名称@软件源地址"
mirror_list_registry=(
    "上海交通大学@docker.mirrors.sjtug.sjtu.edu.cn"
    "网易@hub-mirror.c.163.com"
    "腾讯云@mirror.ccs.tencentyun.com"
    "道客-DaoCloud@f1361db2.m.daocloud.io"
    "微软-Azure(中国)@dockerhub.azk8s.cn"
    "阿里云(杭州)@registry.cn-hangzhou.aliyuncs.com"
    "阿里云(上海)@registry.cn-shanghai.aliyuncs.com"
    "阿里云(青岛)@registry.cn-qingdao.aliyuncs.com"
    "阿里云(北京)@registry.cn-beijing.aliyuncs.com"
    "阿里云(张家口)@registry.cn-zhangjiakou.aliyuncs.com"
    "阿里云(呼和浩特)@registry.cn-huhehaote.aliyuncs.com"
    "阿里云(乌兰察布)@registry.cn-wulanchabu.aliyuncs.com"
    "阿里云(深圳)@registry.cn-shenzhen.aliyuncs.com"
    "阿里云(河源)@registry.cn-heyuan.aliyuncs.com"
    "阿里云(广州)@registry.cn-guangzhou.aliyuncs.com"
    "阿里云(成都)@registry.cn-chengdu.aliyuncs.com"
    "阿里云(香港)@registry.cn-hongkong.aliyuncs.com"
    "阿里云(日本-东京)@registry.ap-northeast-1.aliyuncs.com"
    "阿里云(新加坡)@registry.ap-southeast-1.aliyuncs.com"
    "阿里云(澳大利亚-悉尼)@registry.ap-southeast-2.aliyuncs.com"
    "阿里云(马来西亚-吉隆坡)@registry.ap-southeast-3.aliyuncs.com"
    "阿里云(印度尼西亚-雅加达)@registry.ap-southeast-5.aliyuncs.com"
    "阿里云(印度-孟买)@registry.ap-south-1.aliyuncs.com"
    "阿里云(德国-法兰克福)@registry.eu-central-1.aliyuncs.com"
    "阿里云(英国-伦敦)@registry.eu-west-1.aliyuncs.com"
    "阿里云(美国西部-硅谷)@registry.us-west-1.aliyuncs.com"
    "阿里云(美国东部-弗吉尼亚)@registry.us-east-1.aliyuncs.com"
    "阿里云(阿联酋-迪拜)@registry.me-east-1.aliyuncs.com"
    "阿里云(hinas海纳斯)@z0nkeoyx.mirror.aliyuncs.com"
    "谷歌云@mirror.gcr.io"
    "官方@registry.hub.docker.com"
)

## 定义系统判定变量
SYSTEM_DEBIAN="Debian"
SYSTEM_UBUNTU="Ubuntu"
SYSTEM_KALI="Kali"
SYSTEM_REDHAT="RedHat"
SYSTEM_RHEL="RedHat"
SYSTEM_CENTOS="CentOS"
SYSTEM_CENTOS_STREAM="CentOS Stream"
SYSTEM_ROCKY="Rocky"
SYSTEM_ALMALINUX="AlmaLinux"
SYSTEM_FEDORA="Fedora"
SYSTEM_OPENCLOUDOS="OpenCloudOS"
SYSTEM_OPENEULER="openEuler"

## 定义目录和文件
File_LinuxRelease=/etc/os-release
File_RedHatRelease=/etc/redhat-release
File_OpenCloudOSRelease=/etc/opencloudos-release
File_openEulerRelease=/etc/openEuler-release
File_DebianVersion=/etc/debian_version
File_DebianSourceList=/etc/apt/sources.list
Dir_DebianExtendSource=/etc/apt/sources.list.d
Dir_YumRepos=/etc/yum.repos.d

## 定义 Docker 相关变量
DockerDir=/etc/docker
DockerConfig=$DockerDir/daemon.json
DockerConfigBackup=$DockerDir/daemon.json.bak
DockerVersionFile=docker-version.txt
DockerCEVersionFile=docker-ce-version.txt
DockerCECLIVersionFile=docker-ce-cli-version.txt

## 定义颜色变量
RED='33[31m'
GREEN='33[32m'
YELLOW='33[33m'
BLUE='33[34m'
PLAIN='33[0m'
BOLD='33[1m'
SUCCESS='[33[32mOK33[0m]'
COMPLETE='[33[32mDONE33[0m]'
WARN='[33[33mWARN33[0m]'
ERROR='[33[31mERROR33[0m]'
WORKING='[33[34m*33[0m]'

function StartTitle() {
    [[ -z "${SOURCE}" || -z "${SOURCE_REGISTRY}" ]] && clear
    # echo -e ' +-----------------------------------+'
    # echo -e " | 33[0;1;35;95m⡇33[0m  33[0;1;33;93m⠄33[0m 33[0;1;32;92m⣀⡀33[0m 33[0;1;36;96m⡀33[0;1;34;94m⢀33[0m 33[0;1;35;95m⡀⢀33[0m 33[0;1;31;91m⡷33[0;1;33;93m⢾33[0m 33[0;1;32;92m⠄33[0m 33[0;1;36;96m⡀⣀33[0m 33[0;1;34;94m⡀33[0;1;35;95m⣀33[0m 33[0;1;31;91m⢀⡀33[0m 33[0;1;33;93m⡀33[0;1;32;92m⣀33[0m 33[0;1;36;96m⢀⣀33[0m |"
    # echo -e " | 33[0;1;31;91m⠧33[0;1;33;93m⠤33[0m 33[0;1;32;92m⠇33[0m 33[0;1;36;96m⠇⠸33[0m 33[0;1;34;94m⠣33[0;1;35;95m⠼33[0m 33[0;1;31;91m⠜⠣33[0m 33[0;1;33;93m⠇33[0;1;32;92m⠸33[0m 33[0;1;36;96m⠇33[0m 33[0;1;34;94m⠏33[0m  33[0;1;35;95m⠏33[0m  33[0;1;33;93m⠣⠜33[0m 33[0;1;32;92m⠏33[0m  33[0;1;34;94m⠭⠕33[0m |"
    # echo -e ' +-----------------------------------+'
    echo -e '  欢迎使用 Docker Engine 一键安装脚本'
}

## 报错退出
function Output_Error() {
    [ "$1" ] && echo -e "n$ERROR $1n"
    exit 1
}

## 基础环境判断
function PermissionJudgment() {
    if [ $UID -ne 0 ]; then
        echo -e "n$ERROR 权限不足,请使用 Root 用户运行本脚本n"
        exit 1
    fi
}

## 系统判定变量
function EnvJudgment() {
    ## 定义系统名称
    SYSTEM_NAME="$(cat $File_LinuxRelease | grep -E "^NAME=" | awk -F '=' '{print$2}' | sed "s/['"]//g")"
    cat $File_LinuxRelease | grep "PRETTY_NAME=" -q
    [ $? -eq 0 ] && SYSTEM_PRETTY_NAME="$(cat $File_LinuxRelease | grep -E "^PRETTY_NAME=" | awk -F '=' '{print$2}' | sed "s/['"]//g")"
    ## 定义系统版本号
    SYSTEM_VERSION_NUMBER="$(cat $File_LinuxRelease | grep -E "^VERSION_ID=" | awk -F '=' '{print$2}' | sed "s/['"]//g")"
    ## 定义系统ID
    SYSTEM_ID="$(cat $File_LinuxRelease | grep -E "^ID=" | awk -F '=' '{print$2}' | sed "s/['"]//g")"
    ## 判定当前系统派系
    if [ -s $File_DebianVersion ]; then
        SYSTEM_FACTIONS="${SYSTEM_DEBIAN}"
    elif [ -s $File_openEulerRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_OPENEULER}"
    elif [ -s $File_RedHatRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_REDHAT}"
    elif [ -s $File_OpenCloudOSRelease ]; then
        SYSTEM_FACTIONS="${SYSTEM_OPENCLOUDOS}" # 注:RedHat 判断优先级需要高于 OpenCloudOS,因为8版本基于红帽而9版本不是
    else
        Output_Error "无法判断当前运行环境,当前系统不在本脚本的支持范围内"
    fi
    ## 判定系统名称、版本、版本号
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        if [ ! -x /usr/bin/lsb_release ]; then
            apt-get install -y lsb-release
            if [ $? -ne 0 ]; then
                Output_Error "lsb-release 软件包安装失败n        本脚本需要通过 lsb_release 指令判断系统具体类型和版本,当前系统可能为精简安装,请自行安装后重新执行脚本!"
            fi
        fi
        SYSTEM_JUDGMENT="$(lsb_release -is)"
        SYSTEM_VERSION_CODENAME="${DEBIAN_CODENAME:-"$(lsb_release -cs)"}"
        ;;
    "${SYSTEM_REDHAT}")
        SYSTEM_JUDGMENT="$(cat $File_RedHatRelease | awk -F ' ' '{printf$1}')"
        ## Red Hat Enterprise Linux
        cat $File_RedHatRelease | grep -q "${SYSTEM_RHEL}"
        [ $? -eq 0 ] && SYSTEM_JUDGMENT="${SYSTEM_RHEL}"
        ## CentOS Stream
        cat $File_RedHatRelease | grep -q "${SYSTEM_CENTOS_STREAM}"
        [ $? -eq 0 ] && SYSTEM_JUDGMENT="${SYSTEM_CENTOS_STREAM}"
        ;;
    "${SYSTEM_OPENCLOUDOS}")
        SYSTEM_JUDGMENT="${SYSTEM_OPENCLOUDOS}"
        ;;
    "${SYSTEM_OPENEULER}")
        SYSTEM_JUDGMENT="${SYSTEM_OPENEULER}"
        ;;
    esac
    ## 判定系统处理器架构
    case $(uname -m) in
    x86_64)
        SYSTEM_ARCH="x86_64"
        SOURCE_ARCH="amd64"
        ;;
    aarch64)
        SYSTEM_ARCH="ARM64"
        SOURCE_ARCH="arm64"
        ;;
    armv7l)
        SYSTEM_ARCH="ARMv7"
        SOURCE_ARCH="armhf"
        ;;
    armv6l)
        SYSTEM_ARCH="ARMv6"
        SOURCE_ARCH="armhf"
        ;;
    i386 | i686)
        Output_Error "Docker Engine 不支持安装在 x86_32 架构的环境上!"
        ;;
    *)
        SYSTEM_ARCH=$(uname -m)
        SOURCE_ARCH=armhf
        ;;
    esac
    ## 定义软件源分支名称
    case "${SYSTEM_JUDGMENT}" in
    "${SYSTEM_CENTOS}" | "${SYSTEM_DEBIAN}" | "${SYSTEM_UBUNTU}" | "${SYSTEM_FEDORA}")
        SOURCE_BRANCH="$(echo "${SYSTEM_JUDGMENT,,}" | sed "s/ /-/g")"
        ;;
    "${SYSTEM_CENTOS_STREAM}" | "${SYSTEM_ALMALINUX}" | "${SYSTEM_ROCKY}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        SOURCE_BRANCH="centos"
        ;;
    "${SYSTEM_RHEL}")
        SOURCE_BRANCH="rhel"
        ;;
    "${SYSTEM_KALI}")
        # Kali 使用 Debian 12 的 docker ce 源
        SOURCE_BRANCH="debian"
        SYSTEM_VERSION_CODENAME="bullseye"
        ;;
    *)
        Output_Error "当前系统不在本脚本的支持范围内"
        ;;
    esac
    ## 定义软件源更新文字
    case "${SYSTEM_FACTIONS}" in
    "${SYSTEM_DEBIAN}")
        SYNC_MIRROR_TEXT="更新软件源"
        ;;
    "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
        SYNC_MIRROR_TEXT="生成软件源缓存"
        ;;
    esac
}

# 检查是否安装了bc,如果没有安装,则进行安装
CheckBc() {
    if ! command -v bc &> /dev/null; then
        echo "bc could not be found, attempting to install it..."
        sudo apt-get update
        if ! sudo apt-get install -y bc; then
            echo "Failed to install bc. Please install it manually and rerun the script."
            exit 1
        fi
    fi
}

# 定义一个函数来测试镜像源的下载速度
test_speed() {
    local source=$1
    local image="linuxserver/freshrss" # 使用一个很小的镜像来测试速度
    local start_time

    # 拉取镜像前记录当前时间
    start_time=$(date +%s.%N)

    # 使用指定的镜像源拉取hello-world镜像
    timeout 30 docker pull $source/$image > /dev/null 2>&1

    # 拉取镜像后记录当前时间
    local end_time=$(date +%s.%N)

    # 计算下载时间(秒)
    local download_time=$(echo "$end_time - $start_time" | bc -l)

    echo "$download_time"
}


# 定义一个函数,用于等待一个进程在给定的时间内完成,否则返回超时  
# wait_timeout() {  
#     local pid=$1  
#     local timeout=$2  
#     local kill_signal=TERM  # 默认发送TERM信号  
  
#     # 使用timeout命令等待子进程结束,或者超时后发送信号  
#     timeout $timeout bash -c "while kill -0 $pid 2>/dev/null; do sleep 1; done" || kill -$kill_signal $pid  
#     wait $pid 2>/dev/null  # 等待进程真正结束,忽略任何错误  
#     return $?  # 返回子进程的退出状态  
# }  

# 定义一个函数来测试镜像源的下载速度	
# test_speed() {  
#     local source=$1  
#     local image="xjxjin/alist-sync:1.0.1"  
#     local start_time  
#     local timeout_seconds=30  
  
#     # 拉取镜像前记录当前时间  
#     start_time=$(date +%s.%N)  
  
#     # 将docker pull放入后台运行  
#     docker pull "$source/$image" > /dev/null 2>&1 &  
#     local pull_pid=$!  # 获取后台进程的PID  
  
#     # 等待docker pull完成或者超时  
#     if ! wait_timeout $pull_pid $timeout_seconds; then  
#         # 如果超时,则设置download_time为30秒(作为超时指示)  
#         local download_time=30  
#         echo "下载超时"  
#     else  
#         # 拉取镜像后记录当前时间  
#         local end_time=$(date +%s.%N)  
  
#         # 计算下载时间(秒)  
#         local download_time=$(echo "$end_time - $start_time" | bc -l)  
#     fi  
  
#     echo "$download_time"  
# }  



function ChooseMirrors() {
    ## 打印软件源列表
    function PrintMirrorsList() {
        local tmp_mirror_name tmp_mirror_url arr_num default_mirror_name_length tmp_mirror_name_length tmp_spaces_nums a i j
        ## 计算字符串长度
        function StringLength() {
            local text=$1
            echo "${#text}"
        }
        echo -e ''

        local list_arr=()
        local list_arr_sum="$(eval echo ${#$1[@]})"
        for ((a = 0; a < $list_arr_sum; a++)); do
            list_arr[$a]="$(eval echo ${$1[a]})"
        done
        if [ -x /usr/bin/printf ]; then
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                # tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}') # 软件源地址
                arr_num=$((i + 1))
                default_mirror_name_length=${2:-"30"} # 默认软件源名称打印长度
                ## 补齐长度差异(中文的引号在等宽字体中占1格而非2格)
                [[ $(echo "${tmp_mirror_name}" | grep -c "“") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "“")
                [[ $(echo "${tmp_mirror_name}" | grep -c "”") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "”")
                [[ $(echo "${tmp_mirror_name}" | grep -c "‘") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "‘")
                [[ $(echo "${tmp_mirror_name}" | grep -c "’") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "’")
                # 非一般字符长度
                tmp_mirror_name_length=$(StringLength $(echo "${tmp_mirror_name}" | sed "s| ||g" | sed "s|[0-9a-zA-Z.=:_()'"-/!·]||g;"))
                ## 填充空格
                tmp_spaces_nums=$(($(($default_mirror_name_length - ${tmp_mirror_name_length} - $(StringLength "${tmp_mirror_name}"))) / 2))
                for ((j = 1; j <= ${tmp_spaces_nums}; j++)); do
                    tmp_mirror_name="${tmp_mirror_name} "
                done
                printf " ❖  %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s %4sn" "${tmp_mirror_name}" "$arr_num)"
            done
        else
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}')  # 软件源地址
                arr_num=$((i + 1))
                echo -e " ❖  $arr_num. ${tmp_mirror_url} | ${tmp_mirror_name}"
            done
        fi
    }

    function Title() {
        local system_name="${SYSTEM_PRETTY_NAME:-"${SYSTEM_NAME} ${SYSTEM_VERSION_NUMBER}"}"
        local arch=""${DEVICE_ARCH}""
        local date="$(date "+%Y-%m-%d %H:%M:%S")"
        local timezone="$(timedatectl status 2>/dev/null | grep "Time zone" | awk -F ':' '{print$2}' | awk -F ' ' '{print$1}')"

        echo -e ''
        echo -e " 运行环境 ${BLUE}${system_name} ${arch}${PLAIN}"
        echo -e " 系统时间 ${BLUE}${date} ${timezone}${PLAIN}"
    }

    Title
    local mirror_list_name

    if [[ -z "${SOURCE_REGISTRY}" ]]; then
        mirror_list_name="mirror_list_registry"
        PrintMirrorsList "${mirror_list_name}" 44
        local CHOICE_C=$(echo -e "n${BOLD}└─ 请选择并输入你想使用的 Docker Registry 源 [ 1-$(eval echo ${#$mirror_list_name[@]}) ]:${PLAIN}")

        # 初始化一个数组来存储每个源的速度
        declare -A speed_array

        declare -A speed_index_array  # 用来存储每个源在列表中的索引  
        local fastest_mirrors=()
        # 测试每个源的速度并打印结果
        echo -e "n${BOLD}测试中,请稍候...${PLAIN}"

        local tmp_mirror_name tmp_mirror_url arr_num default_mirror_name_length tmp_mirror_name_length tmp_spaces_nums a i j
        ## 计算字符串长度

        echo -e ''

        local list_arr=()
        local list_arr_sum="$(eval echo ${#${mirror_list_name}[@]})"
        for ((a = 0; a < $list_arr_sum; a++)); do
            list_arr[$a]="$(eval echo ${${mirror_list_name}[a]})"
        done
        if [ -x /usr/bin/printf ]; then
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}') # 软件源地址

                local speed=$(test_speed "$tmp_mirror_url")
                speed_array[$tmp_mirror_name]=$speed
                speed_index_array[$tmp_mirror_name]=$((i+1))
                # local speed=$(test_speed "$tmp_mirror_url")


                arr_num=$((i + 1))
                default_mirror_name_length=${2:-"30"} # 默认软件源名称打印长度
                ## 补齐长度差异(中文的引号在等宽字体中占1格而非2格)
                [[ $(echo "${tmp_mirror_name}" | grep -c "“") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "“")
                [[ $(echo "${tmp_mirror_name}" | grep -c "”") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "”")
                [[ $(echo "${tmp_mirror_name}" | grep -c "‘") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "‘")
                [[ $(echo "${tmp_mirror_name}" | grep -c "’") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "’")
                # 非一般字符长度
                tmp_mirror_name_length=$(StringLength $(echo "${tmp_mirror_name}" | sed "s| ||g" | sed "s|[0-9a-zA-Z.=:_()'"-/!·]||g;"))
                ## 填充空格
                tmp_spaces_nums=$(($(($default_mirror_name_length - ${tmp_mirror_name_length} - $(StringLength "${tmp_mirror_name}"))) / 2))
                for ((j = 1; j <= ${tmp_spaces_nums}; j++)); do
                    tmp_mirror_name="${tmp_mirror_name} "
                done
                
                # speed_index_array[$tmp_mirror_name]=$((i+1))  # 存储源的id值
                if (( $(echo "scale=1; $speed < 1" | bc -l) )); then  
                    printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s 下载速度: %s 秒n" "$arr_num" "${tmp_mirror_name}" "0${speed}"  
                    # speed_index_array[$source]=$((i+1))
                    speed_index_array[$tmp_mirror_name]="$(printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s n" "$arr_num" "${tmp_mirror_name}")"

                else  
                    speed_index_array[$tmp_mirror_name]="$(printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s n" "$arr_num" "${tmp_mirror_name}")"

                    printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s 下载速度: %s 秒n" "$arr_num" "${tmp_mirror_name}" "${speed}"  
                fi
            done
        else
            for ((i = 0; i < ${#list_arr[@]}; i++)); do
                tmp_mirror_name=$(echo "${list_arr[i]}" | awk -F '@' '{print$1}') # 软件源名称
                tmp_mirror_url=$(echo "${list_arr[i]}" | awk -F '@' '{print$2}')  # 软件源地址
                arr_num=$((i + 1))
                echo -e " ❖  $arr_num. ${tmp_mirror_url} | ${tmp_mirror_name}"
            done
        fi

        # 使用sort命令的-k选项对速度和源的配对进行排序,-t选项定义字段分隔符为空格  
        # 注意:这里我们使用process substitution <(...)来避免使用临时文件  
         
        sorted_pairs=$(for source in "${!speed_array[@]}"; do echo "${speed_array[$source]} $source ${speed_index_array[$source]}"; done | sort -k1,1n -t' ' -s)  

        # 提取速度最小的三个源 
        local count=0  
        echo ""
        echo "速度最快的三个源:"  
        while IFS=' ' read -r speed tmp_mirror_name arr_num && [[ $count -lt 3 ]]; do  
            default_mirror_name_length=${2:-"30"} # 默认软件源名称打印长度
                ## 补齐长度差异(中文的引号在等宽字体中占1格而非2格)
            [[ $(echo "${tmp_mirror_name}" | grep -c "“") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "“")
            [[ $(echo "${tmp_mirror_name}" | grep -c "”") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "”")
            [[ $(echo "${tmp_mirror_name}" | grep -c "‘") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "‘")
            [[ $(echo "${tmp_mirror_name}" | grep -c "’") -gt 0 ]] && let default_mirror_name_length+=$(echo "${tmp_mirror_name}" | grep -c "’")
            # 非一般字符长度
            tmp_mirror_name_length=$(StringLength $(echo "${tmp_mirror_name}" | sed "s| ||g" | sed "s|[0-9a-zA-Z.=:_()'"-/!·]||g;"))
            ## 填充空格
            tmp_spaces_nums=$(($(($default_mirror_name_length - ${tmp_mirror_name_length} - $(StringLength "${tmp_mirror_name}"))) / 2))
            for ((j = 1; j <= ${tmp_spaces_nums}; j++)); do
                tmp_mirror_name="${tmp_mirror_name} "
            done

            if (( $(echo "scale=1; $speed < 1" | bc -l) )); then  
                printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s ${RED}下载速度: %s${PLAIN} 秒n" "$arr_num" "${tmp_mirror_name}" "0${speed}"  
            else  
                printf "源%2s %-$(($default_mirror_name_length + ${tmp_mirror_name_length}))s ${RED}下载速度: %s${PLAIN} 秒n" "$arr_num" "${tmp_mirror_name}" "${speed}"  
            fi
            ((count++))  
        done <<< "$sorted_pairs"  
        
        while true; do
            read -p "${CHOICE_C}" INPUT
            case "${INPUT}" in
            [1-9] | [1-9][0-9] | [1-9][0-9][0-9])
                local tmp_source="$(eval echo ${${mirror_list_name}[$(($INPUT - 1))]})"
                if [[ -z "${tmp_source}" ]]; then
                    echo -e "n$WARN 请输入有效的数字序号!"
                else
                    SOURCE_REGISTRY="$(eval echo ${${mirror_list_name}[$(($INPUT - 1))]} | awk -F '@' '{print$2}')"
                    echo "${SOURCE_REGISTRY}"
                    # exit
                    break
                fi
                ;;
            *)
                echo -e "n$WARN 请输入数字序号以选择你想使用的软件源!"
                ;;
            esac
        done
    fi
}

## 关闭防火墙和SELinux
function CloseFirewall() {
    if [ ! -x /usr/bin/systemctl ]; then
        return
    fi
    if [[ "$(systemctl is-active firewalld)" == "active" ]]; then
        if [[ -z "${CLOSE_FIREWALL}" ]]; then
            local CHOICE
            CHOICE=$(echo -e "n${BOLD}└─ 是否关闭防火墙和 SELinux ? [Y/n] ${PLAIN}")
            read -rp "${CHOICE}" INPUT
            [[ -z "${INPUT}" ]] && INPUT=Y
            case "${INPUT}" in
            [Yy] | [Yy][Ee][Ss])
                CLOSE_FIREWALL="true"
                ;;
            [Nn] | [Nn][Oo]) ;;
            *)
                echo -e "n$WARN 输入错误,默认不关闭!"
                ;;
            esac
        fi
        if [[ "${CLOSE_FIREWALL}" == "true" ]]; then
            local SelinuxConfig=/etc/selinux/config
            systemctl disable --now firewalld >/dev/null 2>&1
            [ -s $SelinuxConfig ] && sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" $SelinuxConfig && setenforce 0 >/dev/null 2>&1
        fi
    fi
}


## 安装 Docker Engine
function DockerEngine() {

    ## 修改 Docker Registry 源
    function RegistryMirror() {
        if [[ "${REGISTRY_SOURCEL}" != "registry.hub.docker.com" ]]; then
            if [ -d $DockerDir ] && [ -e $DockerConfig ]; then
                if [ -e $DockerConfigBackup ]; then
                    if [[ "${IGNORE_BACKUP_TIPS}" == "false" ]]; then
                        local CHOICE_BACKUP=$(echo -e "n${BOLD}└─ 检测到已备份的 Docker 配置文件,是否跳过覆盖备份? [Y/n] ${PLAIN}")
                        read -p "${CHOICE_BACKUP}" INPUT
                        [[ -z "${INPUT}" ]] && INPUT=Y
                        case $INPUT in
                        [Yy] | [Yy][Ee][Ss]) ;;
                        [Nn] | [Nn][Oo])
                            echo ''
                            cp -rvf $DockerConfig $DockerConfigBackup 2>&1
                            ;;
                        *)
                            echo -e "n$WARN 输入错误,默认不覆盖!"
                            ;;
                        esac
                    fi
                else
                    cp -rvf $DockerConfig $DockerConfigBackup 2>&1
                    echo -e "n$COMPLETE 已备份原有 Docker 配置文件至 $DockerConfigBackupn"
                fi
                sleep 2s
            else
                mkdir -p $DockerDir >/dev/null 2>&1
                touch $DockerConfig
            fi
            echo -e '{n  "registry-mirrors": ["https://SOURCE"]n}' >$DockerConfig
            sed -i "s|SOURCE|${SOURCE_REGISTRY}|g" $DockerConfig
            systemctl daemon-reload
        fi
    }
    
    RegistryMirror
    systemctl stop docker >/dev/null 2>&1
    systemctl enable --now docker >/dev/null 2>&1
}


## 重启Docker
function RestartDocker() {
    # 询问用户是否需要重启Docker服务以应用配置更改
  local CHOICE_BACKUP=$(echo -e "n${BOLD}└─ 是否重启Docker以使配置文件生效? [Y/n] ${PLAIN}")  
  read -p "${CHOICE_BACKUP}" INPUT  
  [[ -z "${INPUT}" ]] && INPUT=Y  
  case $INPUT in  
      [Yy]|[Yy][Ee][Ss])  
          echo ''  
          echo "重启Docker服务以应用配置更改..."  
          systemctl restart docker  
          echo "重启Docker服务完成"  
          ;;  
      [Nn]|[Nn][Oo])  
          echo "Docker服务未重启。配置更改将不会立即生效。"  
          ;;  
      *)  
          # echo "未知输入,Docker服务未重启。配置更改将不会立即生效。"  
          echo "Docker服务未重启。配置更改将不会立即生效。"  
          ;;  
  esac

}

## 查看版本并验证安装结果
function CheckVersion() {
    if [ -x /usr/bin/docker ]; then
        echo -en "n验证安装版本:"
        docker -v
        VERIFICATION_DOCKER=$?
        if [ ${VERIFICATION_DOCKER} -eq 0 ]; then
            echo -e "n$COMPLETE 安装完成"
        else
            echo -e "n$ERROR 安装失败"
            case "${SYSTEM_FACTIONS}" in
            "${SYSTEM_DEBIAN}")
                echo -e "n检查源文件:cat $Dir_DebianExtendSource/docker.list"
                echo -e '请尝试手动执行安装命令: apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginn'
                echo ''
                ;;
            "${SYSTEM_REDHAT}" | "${SYSTEM_OPENCLOUDOS}" | "${SYSTEM_OPENEULER}")
                echo -e "n检查源文件:cat $Dir_YumRepos/docker.repo"
                echo -e '请尝试手动执行安装命令: yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginn'
                ;;
            esac
            exit 1
        fi
        if [[ $(systemctl is-active docker) != "active" ]]; then
            sleep 2
            systemctl disable --now docker >/dev/null 2>&1
            sleep 2
            systemctl enable --now docker >/dev/null 2>&1
            sleep 2
            if [[ $(systemctl is-active docker) != "active" ]]; then
                echo -e "n$ERROR 检测到 Docker 服务启动异常,可能由于重复安装导致"
                echo -e "n${YELLOW} 请执行 "systemctl start docker" 或 "service docker start" 命令尝试启动,如若报错请尝试重新执行本脚本${PLAIN}"
            fi
        fi
    else
        echo -e "n$ERROR 安装失败n"
    fi
}

## 运行结束
function RunEnd() {
    echo -e "n     ------ 脚本执行结束 ------"
    # echo -e ' 33[0;1;35;95m┌─33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m──33[0;1;36;96m──33[0;1;34;94m──33[0;1;35;95m──33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m──33[0;1;36;96m──33[0;1;34;94m──33[0;1;35;95m──33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m──33[0;1;36;96m┐33[0m'
    # echo -e ' 33[0;1;31;91m│▞33[0;1;33;93m▀▖33[0m            33[0;1;32;92m▙▗33[0;1;36;96m▌33[0m      33[0;1;31;91m▗33[0;1;33;93m▐33[0m     33[0;1;34;94m│33[0m'
    # echo -e ' 33[0;1;33;93m│▚33[0;1;32;92m▄33[0m 33[0;1;36;96m▌33[0m 33[0;1;34;94m▌▛33[0;1;35;95m▀▖33[0;1;31;91m▞▀33[0;1;33;93m▖▙33[0;1;32;92m▀▖33[0;1;36;96m▌▘33[0;1;34;94m▌▝33[0;1;35;95m▀▖33[0;1;31;91m▛▀33[0;1;33;93m▖▄33[0;1;32;92m▜▀33[0m 33[0;1;36;96m▞33[0;1;34;94m▀▖33[0;1;35;95m│33[0m'
    # echo -e ' 33[0;1;32;92m│▖33[0m 33[0;1;36;96m▌33[0;1;34;94m▌33[0m 33[0;1;35;95m▌▙33[0;1;31;91m▄▘33[0;1;33;93m▛▀33[0m 33[0;1;32;92m▌33[0m  33[0;1;34;94m▌33[0m 33[0;1;35;95m▌▞33[0;1;31;91m▀▌33[0;1;33;93m▌33[0m 33[0;1;32;92m▌▐33[0;1;36;96m▐33[0m 33[0;1;34;94m▖▌33[0m 33[0;1;35;95m▌33[0;1;31;91m│33[0m'
    # echo -e ' 33[0;1;36;96m│▝33[0;1;34;94m▀33[0m 33[0;1;35;95m▝▀33[0;1;31;91m▘▌33[0m  33[0;1;32;92m▝▀33[0;1;36;96m▘▘33[0m  33[0;1;35;95m▘33[0m 33[0;1;31;91m▘▝33[0;1;33;93m▀▘33[0;1;32;92m▘33[0m 33[0;1;36;96m▘▀33[0;1;34;94m▘▀33[0m 33[0;1;35;95m▝33[0;1;31;91m▀33[0m 33[0;1;33;93m│33[0m'
    # echo -e ' 33[0;1;34;94m└─33[0;1;35;95m──33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m──33[0;1;36;96m──33[0;1;34;94m──33[0;1;35;95m──33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m──33[0;1;36;96m──33[0;1;34;94m──33[0;1;35;95m──33[0;1;31;91m──33[0;1;33;93m──33[0;1;32;92m┘33[0m'
    # echo -e "     33[1;34mPowered by linuxmirrors.cn33[0mn"
}


function PrintXJXJin() {
    echo -e "n     ------ xjxjin ------"
    echo -e ' 33[0;1;35m┌─33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0;1;36m──33[0;1;34m──33[0;1;35m──33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0;1;36m──33[0;1;34m──33[0;1;35m──33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0m'
    echo -e ' 33[0;1;31m│33[0;1;33m▓33[0m33[0;1;32mX33[0;1;36mj33[0;1;34mx33[0;1;35mJ33[0;1;31mx33[0;1;33m▓33[0m     33[0;1;34m│'
    echo -e ' 33[0;1;33m│33[0;1;32mx33[0;1;36mj33[0;1;34mX33[0;1;35mj33[0;1;31mX33[0;1;33mj33[0;1;32mx33[0m 33[0;1;36m▓33[0;1;34m│'
    echo -e ' 33[0;1;32m│33[0;1;36m▓33[0m 33[0;1;34mX33[0;1;35mj33[0;1;31mX33[0;1;33mj33[0;1;32mX33[0;1;36mj33[0m 33[0;1;34m▓33[0m 33[0;1;32m│'
    echo -e ' 33[0;1;36m│33[0;1;34m▓33[0m 33[0;1;35mX33[0;1;31mj33[0;1;33mX33[0;1;32mj33[0;1;36mX33[0;1;34mj33[0m 33[0;1;35m▓33[0m 33[0;1;36m│'
    echo -e ' 33[0;1;34m└─33[0;1;35m──33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0;1;36m──33[0;1;34m──33[0;1;35m──33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0;1;36m──33[0;1;34m──33[0;1;35m──33[0;1;31m──33[0;1;33m──33[0;1;32m──33[0m'
    echo -e "     33[1;34mPowered by linuxmirrors.cn33[0mn"
}


## 处理命令选项
function CommandOptions() {
    ## 命令帮助
    function Output_Help_Info() {
        echo -e "
命令选项(参数名/含义/参数值):

  --source                 指定 Docker CE 源地址                     地址
  --source-registry        指定 Docker Registry 源地址               地址
  --codename               指定 Debian 系操作系统的版本代号          代号名称
  --install-latested       控制是否安装最新版本的 Docker Engine      true 或 false
  --ignore-backup-tips     忽略覆盖备份提示                          无

问题报告 https://github.com/SuperManito/LinuxMirrors/issues
  "
    }

    ## 判断参数
    while [ $# -gt 0 ]; do
        case "$1" in
        ## 指定 Docker CE 软件源地址
        --source)
            if [ "$2" ]; then
                echo "$2" | grep -Eq "(|)|[|]|{|}"
                if [ $? -eq 0 ]; then
                    Output_Error "检测到无效参数值 ${BLUE}$2${PLAIN} ,请输入有效的地址!"
                else
                    SOURCE="$(echo "$2" | sed -e 's,^http[s]?://,,g' -e 's,/$,,')"
                    shift
                fi
            else
                Output_Error "检测到 ${BLUE}$1${PLAIN} 为无效参数,请在该参数后指定软件源地址!"
            fi
            ;;
        ## 指定 Docker Registry 仓库地址
        --source-registry)
            if [ "$2" ]; then
                echo "$2" | grep -Eq "(|)|[|]|{|}"
                if [ $? -eq 0 ]; then
                    Output_Error "检测到无效参数值 ${BLUE}$2${PLAIN} ,请输入有效的地址!"
                else
                    SOURCE_REGISTRY="$(echo "$2" | sed -e 's,^http[s]?://,,g' -e 's,/$,,')"
                    shift
                fi
            else
                Output_Error "检测到 ${BLUE}$1${PLAIN} 为无效参数,请在该参数后指定软件源地址!"
            fi
            ;;
        ## 指定 Debian 版本代号
        --codename)
            if [ "$2" ]; then
                DEBIAN_CODENAME="$2"
                shift
            else
                Output_Error "检测到 ${BLUE}$1${PLAIN} 为无效参数,请在该参数后指定版本代号!"
            fi
            ;;
        ## 安装最新版本
        --install-latested)
            if [ "$2" ]; then
                case "$2" in
                [Tt]rue | [Ff]alse)
                    INSTALL_LATESTED_DOCKER="${2,,}"
                    shift
                    ;;
                *)
                    Output_Error "检测到 ${BLUE}$2${PLAIN} 为无效参数值,请在该参数后指定 true 或 false 作为参数值!"
                    ;;
                esac
            else
                Output_Error "检测到 ${BLUE}$1${PLAIN} 为无效参数,请在该参数后指定 true 或 false 作为参数值!"
            fi
            ;;
        ## 忽略覆盖备份提示
        --ignore-backup-tips)
            IGNORE_BACKUP_TIPS="true"
            ;;
        ## 命令帮助
        --help)
            Output_Help_Info
            exit
            ;;
        *)
            Output_Error "检测到 ${BLUE}$1${PLAIN} 为无效参数,请确认后重新输入!"
            ;;
        esac
        shift
    done
    ## 给部分命令选项赋予默认值
    IGNORE_BACKUP_TIPS="${IGNORE_BACKUP_TIPS:-"false"}"
}

## 组合函数
function Combin_Function() {
    
    ## 基础环境判断
    PermissionJudgment
    ## 系统判定变量
    # EnvJudgment
    ## 检查bc是否安装
    CheckBc
    ## 欢迎使用 Docker Engine 一键安装脚本
    StartTitle
    ## 打印软件源列表
    ChooseMirrors
    ## 关闭防火墙和SELinux
    CloseFirewall
    ## 安装 Docker Engine
    DockerEngine
    # 重启docker
    RestartDocker
    ## 查看版本并验证安装结果
    CheckVersion
    ## 运行结束
    RunEnd
}

CommandOptions "$@"
Combin_Function

2.将其中的linuxserver/freshrss 更换为自己想要的docker项目名。

3.用shell链接工具比如finalshell连接自己的服务器。

4.终端中输入 bash <(curl -sSL 域名地址/ceshi.sh)

5.按步骤运行脚本就可以了,最后就可以在自己的docker中看到已经拉取成功的项目名,比如dockerhub.azk8s.cn/linuxserver/freshrss 类似这样的。

6.在脚本中找到是哪家的镜像地址,最后在终端中输入对应的数字最后重启docker就可以了。

结语

这种虽然很麻烦,但是是目前能够拉取镜像最快的方法了。

如果还不能解决问题,就去https://github.com/SuperManito/LinuxMirrors项目地址里找到最新的方法。

  • ✇新锐博客
  • Docker更换国内镜像源莫忘
    前言 因为使用了国内服务器,所以有些时候感觉拉取docker镜像有点慢。这次索性就更换一下国内的镜像源。 国内镜像源 、阿里云镜像站:(需登录,免费) https://<your_code>.mirror.aliyuncs.com 2、网易云镜像站: https://hub-mirror.c.163.com 3、百度云镜像站: https://mirror.baidubce.com 4、上海交大镜像站: https://docker.mirrors.sjtug.sjtu.edu.cn 5、南京大学镜像站: https://docker.nju.edu.cn 阿里镜像申请 登录:https://cr.console.aliyun.com 点击“创建我的容器镜像”,得到专属加速地址。 更换镜像源 创建或修改 /etc/docker/daemon.json 文件,修改为如下形式 { "registry-mirrors": [ "https://registry.hub.docker.com", "https://hub-mirror.
     

Docker更换国内镜像源

作者 莫忘
2024年5月19日 12:08

前言

因为使用了国内服务器,所以有些时候感觉拉取docker镜像有点慢。这次索性就更换一下国内的镜像源。

国内镜像源

、阿里云镜像站:(需登录,免费)

https://<your_code>.mirror.aliyuncs.com

2、网易云镜像站:

https://hub-mirror.c.163.com

3、百度云镜像站:

https://mirror.baidubce.com

4、上海交大镜像站:

https://docker.mirrors.sjtug.sjtu.edu.cn

5、南京大学镜像站:

https://docker.nju.edu.cn		

阿里镜像申请

登录:https://cr.console.aliyun.com

点击“创建我的容器镜像”,得到专属加速地址。

图片[1]-新锐博客

更换镜像源

创建或修改 /etc/docker/daemon.json 文件,修改为如下形式

{
    "registry-mirrors": [
        "https://registry.hub.docker.com",
        "https://hub-mirror.c.163.com",
        "https://mirror.baidubce.com",
        "https://docker.mirrors.sjtug.sjtu.edu.cn",
        "https://docker.nju.edu.cn"
    ]
}

加载重启docker

systemctl restart docker

查看是否成功

docker info

图片[2]-新锐博客

  • ✇新锐博客
  • Docker 搭建Lobe Chat莫忘
    前言 之前推荐过chatgpt-next-web,但是感觉页面并没有很还原openai,所以找到了这个相似度很高的Lobe Chat。 教程 命令安装 $ docker run -d -p 3210:3210 -e OPENAI_API_KEY=sk-xxxx -e OPENAI_PROXY_URL=https://api-proxy.com/v1 -e ACCESS_CODE=lobe66 --name lobe-chat lobehub/lobe-chat 其中OPENAI_PROXY_URL 可以设置为第三方代理OPENAI服务。 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:lobehub/lobe-chat ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入3210,服务器端口自定义。 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以
     

Docker 搭建Lobe Chat

作者 莫忘
2024年5月14日 11:38

前言

之前推荐过chatgpt-next-web,但是感觉页面并没有很还原openai,所以找到了这个相似度很高的Lobe Chat。

教程

命令安装

$ docker run -d -p 3210:3210 
  -e OPENAI_API_KEY=sk-xxxx 
  -e OPENAI_PROXY_URL=https://api-proxy.com/v1 
  -e ACCESS_CODE=lobe66 
  --name lobe-chat 
  lobehub/lobe-chat

其中OPENAI_PROXY_URL 可以设置为第三方代理OPENAI服务。

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入:lobehub/lobe-chat ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入3210,服务器端口自定义。

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

相关

开源地址:https://github.com/lobehub/lobe-chat/blob/main/README.zh-CN.md

镜像站:https://hub.yzuu.cf/lobehub/lobe-chat/blob/main/README.zh-CN.md

官方文档:https://lobehub.com/zh/docs/usage/start

  • ✇新锐博客
  • Docker 搭建 Rss 阅读器 freshrss莫忘
    前言 逛了不少博客,发现WordPress默认还是有rss订阅功能的,比如访问域名+/feed 。 RSS(Really Simple Syndication)是一种用于发布和订阅网站内容的标准格式,而 FreshRSS 是一款自托管的开源 RSS 阅读器。 并且 FreshRSS 提供了非常简洁的界面,可以自行添加分类和订阅源, 教程 命令安装 docker run -d --name freshrss -p 8090:80 -v /home/docker/freshrss/data:/config -e TZ=Asia/Shanghai --restart unless-stopped linuxserver/freshrss:latest 设置 1.首先将语言设置为简体中文 2.数据库类型选择SQlite即可 3.设置用户名和密码 4.找到订阅管理,把默认的给清空即可。 5.添加分类和订阅  
     

Docker 搭建 Rss 阅读器 freshrss

作者 莫忘
2024年5月10日 14:18

前言

逛了不少博客,发现WordPress默认还是有rss订阅功能的,比如访问域名+/feed 。

RSS(Really Simple Syndication)是一种用于发布和订阅网站内容的标准格式,而 FreshRSS 是一款自托管的开源 RSS 阅读器。

并且 FreshRSS 提供了非常简洁的界面,可以自行添加分类和订阅源,

教程

命令安装

docker run -d 
--name freshrss 
-p 8090:80 
-v /home/docker/freshrss/data:/config 
-e TZ=Asia/Shanghai 
--restart unless-stopped 
linuxserver/freshrss:latest

设置

1.首先将语言设置为简体中文

图片[1]-新锐博客

2.数据库类型选择SQlite即可

图片[2]-新锐博客

3.设置用户名和密码

图片[3]-新锐博客

4.找到订阅管理,把默认的给清空即可。

图片[4]-新锐博客5.添加分类和订阅

图片[5]-新锐博客

 

  • ✇新锐博客
  • Docker 搭建在线工具网站 - it-tools莫忘
    前言 之前介绍过彩虹工具网,那个需要下载文件自己设置伪静态等。it-tools是一个开源工具箱项目,作者来自海外,项目地址:IT TOOLS,原作者是 Corentin Thomasset,汉化由qingfeng2336提供Docker镜像,IT-Tools 采用 Vue.js (Vue 3) 和 Naive UI 组件库制作。 有群晖的小伙伴可以部署在群晖上。 教程 拉取it-tools镜像 docker pull corentinth/it-tools:latest 运行it-tools容器 docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-tools:latest 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以通过网站访问了。
     

Docker 搭建在线工具网站 - it-tools

作者 莫忘
2024年4月15日 23:53

前言

之前介绍过彩虹工具网,那个需要下载文件自己设置伪静态等。it-tools是一个开源工具箱项目,作者来自海外,项目地址:IT TOOLS,原作者是 Corentin Thomasset,汉化由qingfeng2336提供Docker镜像,IT-Tools 采用 Vue.js (Vue 3) 和 Naive UI 组件库制作。

有群晖的小伙伴可以部署在群晖上。

教程

拉取it-tools镜像

docker pull corentinth/it-tools:latest

运行it-tools容器

docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-tools:latest

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

  • ✇新锐博客
  • 雷池waf - 开源免费社区版莫忘
    前言 在搭建网站的过程中免不了被人恶意攻击,这时候waf就派上用场了,而开源的雷池WAF就是其中的佼佼者。 教程 在线安装 官方脚本 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" 华为云加速 CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" 流式安装 STREAM=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)" 离线安装 1.下载雷池WAF安装包,需要安装好docker环境。 2.解压压缩包 cat image.tar.gz | gzip -d | docker load 3.进入雷池安装目录 mkdir -p safeline && cd safeline # 创建 safeline 目录并且进入 4.生成安装环境 cat >>
     

雷池waf - 开源免费社区版

作者 莫忘
2024年4月15日 22:49

前言

在搭建网站的过程中免不了被人恶意攻击,这时候waf就派上用场了,而开源的雷池WAF就是其中的佼佼者。

教程

在线安装

官方脚本
bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
华为云加速
CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
流式安装
STREAM=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"

离线安装

1.下载雷池WAF安装包,需要安装好docker环境。

2.解压压缩包

cat image.tar.gz | gzip -d | docker load

3.进入雷池安装目录

mkdir -p safeline  &&  cd safeline    # 创建 safeline 目录并且进入

4.生成安装环境

cat >> .env <<EOF
SAFELINE_DIR=$(pwd)
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=chaitin
EOF

5.启用雷池

docker compose up -d

 

 

 

 

  • ✇新锐博客
  • Docker 搭建轻量高颜值个人导航页面莫忘
    前言 Flare是一款轻量、快速、美观个人导航页面,适用于 HomeLab 或其它注重私密的场景。 可支持 Docker 一键部署,维护方便。 无任何数据库依赖。应用数据完全开放透明。 支持在线编辑。支持 x86 及常见的 ARM 设备。应用资源消耗很低。 截图 特点 服务资源消耗极低,可以跑在任何规格的机器上。 程序页面性能较好,渲染速度更快,支持同时渲染大量书签。 使用声明的配置来进行导航内容管理,无需担心数据迁移问题。 简化了天气数据的获取方式,不再需要申请天气网站的 API_KEY,避免不必要的成本开销。 内置大量风格统一、高质量的矢量图标,确保界面长期耐看。 默认使用免登陆的模式,避免了 HomeLab、本地使用的用户有额外登录操作。 教程 1.命令搭建 docker run -d -p 5005:5005 -v `pwd`/app:/app soulteary/flare 2.docker-compose搭建 version: '3.6' services: flare: image: soulteary/flare restart: always
     

Docker 搭建轻量高颜值个人导航页面

作者 莫忘
2024年3月28日 23:32

前言

Flare是一款轻量、快速、美观个人导航页面,适用于 HomeLab 或其它注重私密的场景。

可支持 Docker 一键部署,维护方便。

无任何数据库依赖。应用数据完全开放透明。

支持在线编辑。支持 x86 及常见的 ARM 设备。应用资源消耗很低。

截图

图片[1]-新锐博客

特点

服务资源消耗极低,可以跑在任何规格的机器上。

程序页面性能较好,渲染速度更快,支持同时渲染大量书签。

使用声明的配置来进行导航内容管理,无需担心数据迁移问题。

简化了天气数据的获取方式,不再需要申请天气网站的 API_KEY,避免不必要的成本开销。

内置大量风格统一、高质量的矢量图标,确保界面长期耐看。

默认使用免登陆的模式,避免了 HomeLab、本地使用的用户有额外登录操作。

教程

1.命令搭建
docker run -d -p 5005:5005 -v `pwd`/app:/app soulteary/flare
2.docker-compose搭建
version: '3.6'

services:
  flare:
    image: soulteary/flare
    restart: always
    # 默认无需添加任何参数,如有特殊需求
    # 可阅读文档 https://github.com/soulteary/docker-flare/blob/main/docs/advanced-startup.md
    command: flare
    # 启用账号登陆模式
    # command: flare --nologin=0
    # environment:
      # 如需开启用户登陆模式,需要先设置 `nologin` 启动参数为 `0`
      # 如开启 `nologin`,未设置 FLARE_USER,则默认用户为 `flare`
      # - FLARE_USER=flare
      # 指定你自己的账号密码,如未设置 `FLARE_USER`,则会默认生成密码并展示在应用启动日志中
      # - FLARE_PASS=your_password
      # 是否开启“使用向导”,访问 `/guide`
      # - FLARE_GUIDE=1
    ports:
      - 5005:5005
    volumes:
      - ./app:/app

然后执行就行

docker-compose up -d

 

  • ✇新锐博客
  • Docker 搭建自用网站数据统计工具Umami莫忘
    前言 搭建网站的朋友都需要用到数据统计,如果对数据统计没什么太大的要求,只想知道当天有多少访问量就可以使用这个Umami。 界面截图 教程 本次教程分为两个部分,一个是一键部署,一个是通过Docker-Compose。 1.一键部署 1.使用宝塔面板的朋友可以将宝塔面板升级到最新版本,自带的Docker应用商店搜索Umami就行了。 2.安装成功后在页面中选择管理 这里我已经安装了,所以显示是重建应用,一般是安装应用。 3.从访问信息中获取到应用的URL地址,一般为ip+端口3000。 4.宝塔面板新建网站php版本选择纯静态,设置中找到反向代理,填写名称和ip+端口3000即可。 2.Docker-Compose 1.新建docker-compose.yaml,并将如下代码加进去 version: '3' services: umami: container_name: umami image: umamisoftware/umami:postgresql-latest ports: - "3000:3000" environme
     

Docker 搭建自用网站数据统计工具Umami

作者 莫忘
2024年3月24日 16:34

前言

搭建网站的朋友都需要用到数据统计,如果对数据统计没什么太大的要求,只想知道当天有多少访问量就可以使用这个Umami。

界面截图

图片[1]-新锐博客

教程

本次教程分为两个部分,一个是一键部署,一个是通过Docker-Compose。

1.一键部署

1.使用宝塔面板的朋友可以将宝塔面板升级到最新版本,自带的Docker应用商店搜索Umami就行了。

图片[2]-新锐博客

2.安装成功后在页面中选择管理

图片[3]-新锐博客

这里我已经安装了,所以显示是重建应用,一般是安装应用。

3.从访问信息中获取到应用的URL地址,一般为ip+端口3000。

4.宝塔面板新建网站php版本选择纯静态,设置中找到反向代理,填写名称和ip+端口3000即可。

2.Docker-Compose

1.新建docker-compose.yaml,并将如下代码加进去

version: '3'
services:
  umami:
    container_name: umami
    image: umamisoftware/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:umami@db:5432/umami
      DATABASE_TYPE: postgresql
      HASH_SALT: replace-me-with-a-random-string
    depends_on:
      - db
    restart: always
  db:
    container_name: umami-db
    image: postgres:12-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
      - ./umami-db-data:/var/lib/postgresql/data
    restart: always

2.启动docker-compose

docker-compose up -d

访问网站

默认账号密码:admin/umami

设置

先别添加网站,右上角地球标志设置语言为中文,再去后台把账号密码重新设置一下,然后再添加网站,并且获取到跟踪代码以及分享代码。

  • ✇新锐博客
  • Docker 部署私有ChatGPT服务附带免费key莫忘
    前言 自从chatgpt出来以后,很多人都听说过AI但是没有用过,今天给大家带来部署自己私有的chatgpt服务。 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:yidadaa/chatgpt-next-web ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入3000,服务器端口自定义。 6.变量需要设置三个分别是OPENAI_API_KEY(key) ,CODE(访问密码) 和BASE_URL(接口地址) 。 自动安装 docker pull yidadaa/chatgpt-next-web docker run -d -p 3000:3000 -e OPENAI_API_KEY=sk-xxxx -e CODE=your-password yidadaa/chatgpt-next-web 还可以设置代理访问,命令如下 docker run -d -p 3000:3000 -e OPENAI_API_KEY=sk
     

Docker 部署私有ChatGPT服务附带免费key

作者 莫忘
2024年2月14日 20:21

前言

自从chatgpt出来以后,很多人都听说过AI但是没有用过,今天给大家带来部署自己私有的chatgpt服务。

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入:yidadaa/chatgpt-next-web ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入3000,服务器端口自定义。

6.变量需要设置三个分别是OPENAI_API_KEY(key)CODE(访问密码) 和BASE_URL(接口地址)

自动安装

docker pull yidadaa/chatgpt-next-web

docker run -d -p 3000:3000 
   -e OPENAI_API_KEY=sk-xxxx 
   -e CODE=your-password 
   yidadaa/chatgpt-next-web

还可以设置代理访问,命令如下

docker run -d -p 3000:3000 
   -e OPENAI_API_KEY=sk-xxxx 
   -e CODE=your-password 
   -e PROXY_URL=https://localhost:7890 
   yidadaa/chatgpt-next-web

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

结语

想要领取免费key和key购买地址请登录查看

免费key领取进入页面后,点击领取免费key,约60次/小时

付费key,30块3.5中度使用,可以用一年

如果使用免费key需要将BASE_URL设置成https://api.chatanywhere.tech

  • ✇新锐博客
  • Docker 搭建聚合实时热榜Dailyhot莫忘
    前言 每天看一下热搜是当代年轻人几乎每天必做的一些事情,而把所有热点事件聚合在一起那就很省时间了,所以今天教大家如何用docker搭建由imsyy大神开源的Dailyhot。 项目地址 项目地址:imsyy/DailyHotApi: 今日热榜 API,一个聚合热门数据的 API 接口,支持 Vercel 部署 整合地址:https://github.com/rehiy/dailyhot-docker 界面截图 安装教程 API接口 安装命令如下 docker run -d --name dailyhot-api --restart always -p 6688:6688 imsyy/dailyhot-api:latest 前端 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:wbsu2003/dailyhot  ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入80,服务器端口自定义。 6.修改环境变量 VITE_GLOBAL_API=https:/
     

Docker 搭建聚合实时热榜Dailyhot

作者 莫忘
2024年1月29日 04:02

前言

每天看一下热搜是当代年轻人几乎每天必做的一些事情,而把所有热点事件聚合在一起那就很省时间了,所以今天教大家如何用docker搭建由imsyy大神开源的Dailyhot。

项目地址

项目地址:imsyy/DailyHotApi: 今日热榜 API,一个聚合热门数据的 API 接口,支持 Vercel 部署

整合地址:https://github.com/rehiy/dailyhot-docker

界面截图

图片[1]-新锐博客

安装教程

API接口

安装命令如下

docker run -d 
--name dailyhot-api 
--restart always 
-p 6688:6688 
imsyy/dailyhot-api:latest

前端

1.进入宝塔面板找到Docker,并且安装Docker管理器 。

2.找到镜像,点击从仓库中拉取。

3.选择官方镜像库,输入:wbsu2003/dailyhot  ,接着等待获取成功。

4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。

5.容器端口输入80,服务器端口自定义。

6.修改环境变量 VITE_GLOBAL_API=https://hot-api.yourwebsite.cn

7.修改环境变量 VITE_ICP=没有可以不填icp备案号

 

  • ✇新锐博客
  • Docker 搭建图片无损压缩工具Squoosh莫忘
    前言 平时无论生活还是搭建网站的过程中都需要用到大量的图片,一张图片的大小就有几MB或者几十MB,数量一旦多起来就会很大了。Squoosh 是一款由 Google 开发的在线图像压缩工具,它允许用户将高分辨率图片转换为小尺寸的压缩图片,以便更快地加载和在网络上共享。 界面截图 手动安装 1.进入宝塔面板找到Docker,并且安装Docker管理器 。 2.找到镜像,点击从仓库中拉取。 3.选择官方镜像库,输入:hausen1012/squoosh:latest ,接着等待获取成功。 4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。 5.容器端口输入80,服务器端口自定义。 命令安装 安装命令如下 docker run -d --name squoosh -p 8000:80 hausen1012/squoosh:latest 设置反代 1.宝塔新建网站,PHP版本选择纯静态。 2.找到反向代理,添加反向代理,URL为ip+端口 3.反代设置完成,可以通过网站访问了。
     

Docker 搭建图片无损压缩工具Squoosh

作者 莫忘
2024年1月27日 19:28

前言

平时无论生活还是搭建网站的过程中都需要用到大量的图片,一张图片的大小就有几MB或者几十MB,数量一旦多起来就会很大了。Squoosh 是一款由 Google 开发的在线图像压缩工具,它允许用户将高分辨率图片转换为小尺寸的压缩图片,以便更快地加载和在网络上共享。

界面截图

图片[1]-新锐博客

手动安装

1.进入宝塔面板找到Docker,并且安装Docker管理器 。
2.找到镜像,点击从仓库中拉取。
3.选择官方镜像库,输入:hausen1012/squoosh:latest ,接着等待获取成功。
4.找到容器,并且创建新的容器,镜像选择刚刚获取成功的镜像。
5.容器端口输入80,服务器端口自定义。

命令安装

安装命令如下

docker run -d 
--name squoosh 
-p 8000:80 
hausen1012/squoosh:latest

设置反代

1.宝塔新建网站,PHP版本选择纯静态。

2.找到反向代理,添加反向代理,URL为ip+端口

3.反代设置完成,可以通过网站访问了。

  • ✇新锐博客
  • Docker 搭建基于webstack的hugo导航站莫忘
    前言 很多时候我们需要各种各样的网站来帮助我们完成一些事情,这时候导航站就很有用了。 简介 WebStack是一个很有名的开源导航站,众多开发者一起开发了多个框架语言的版本,其中shenweiyan大佬开发的hugo版本很轻量,也容易部署,这里推荐给大家。 我们这里搭建的思路是,启动一个hugo服务容器,然后服务文件映射到魔改版的WebStack项目上。 界面截图 部署 1.创建项目文件夹 mkdir webstack_hugo 2.在改该目录下拉取主题 cd webstack_hugo mkdir temp mkdir themes cd temp git clone https://github.com/shenweiyan/WebStack-Hugo.git  3.复制主题到webstack_hugo目录下 cd ~ cd webstack_hugo # 复制WebStack-Hugo 的 conifg.toml 等文件到 hugo 文件夹下 cp -r ./temp/WebStack-Hugo/exampleSite/* ./ # 将WebStack-Hugo 的 examp
     

Docker 搭建基于webstack的hugo导航站

作者 莫忘
2024年1月13日 13:53

前言

很多时候我们需要各种各样的网站来帮助我们完成一些事情,这时候导航站就很有用了。

简介

WebStack是一个很有名的开源导航站,众多开发者一起开发了多个框架语言的版本,其中shenweiyan大佬开发的hugo版本很轻量,也容易部署,这里推荐给大家。

我们这里搭建的思路是,启动一个hugo服务容器,然后服务文件映射到魔改版的WebStack项目上。

界面截图

图片[1]-新锐博客

部署

1.创建项目文件夹
mkdir webstack_hugo
2.在改该目录下拉取主题
cd webstack_hugo
mkdir temp
mkdir themes
cd temp
git clone https://github.com/shenweiyan/WebStack-Hugo.git
 3.复制主题到webstack_hugo目录下
cd ~
cd webstack_hugo
# 复制WebStack-Hugo 的 conifg.toml 等文件到 hugo 文件夹下
cp -r ./temp/WebStack-Hugo/exampleSite/* ./
# 将WebStack-Hugo 的 exampleSite 样式复制到 Hugo 的 themes 文件夹下
cp -r ./temp/* ./themes
4.启动项目
docker run -itd -p 8080:1313 --name webstack-hugo  --restart always -v $(pwd):/src klakegg/hugo server -D

映射webstack_hugo文件夹到容器hugo工程目录,并对外映射端口为8080。

浏览器打开ip:8080即可访问。

5.自定义修改导航

主要的配置信息都集成到了 config.toml
导航的各个信息都集成在 data/webstack.yml 文件中

每次修改后无需重启容器

❌
❌