首页
关于
Search
1
AdGuardHome 安装及部署教程
42,163 阅读
2
搭建基于telegram的无限网盘
10,332 阅读
3
关于微软Azure学生白嫖指南
10,258 阅读
4
Oracle开放全部端口并关闭防火墙
10,105 阅读
5
最新Cloudflare免费自选IP教程(非Partner)
9,615 阅读
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
登录
Search
标签搜索
docker
张至顺
PHP
图床
Cloudflare
金刚长寿功
内网穿透
PT
qBittorrent
阿里云
onedrive
telegram
代理
青龙
FRP
python
一键
telegraph
ipv6
cf_workers
myedunote
累计撰写
113
篇文章
累计收到
1
条评论
首页
栏目
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
页面
关于
搜索到
19
篇与
docker
的结果
2025-01-12
Docker 部署免维护的 IPTV 直播源 + 点播聚合 m3u 的教程
原文地址 https://wp.gxnas.com/15153.html一、安装2025 年 1 月 2 日更新:由于作者防止项目泛滥加入了鉴权,操作步骤改成:①先到【这里 】生成 AES 密钥,同时把系统生成的 AES 密钥复制;②加入【作者 Telegram 交流群 】,并打开【作者 Telegram 鉴权机器人 】,粘贴 AES 密钥,生成 Userid 和专属 Token(注意:此步骤需要科学出国的网络环境以及登录 Telegram);③填入申请到得上一步骤生成的 Userid 和 Token 两个参数,生成一键部署 docker 的命令;④回到群晖 SSH 下,粘贴命令运行。使用 Docker 方式或者使用 Docker compose 方式部署二选一(本教程用 “2、Docker compose 方式”);由于 docker 域名被墙,网络环境需要保证 docker 可以正常拉取镜像,如果镜像无法拉取的,请参考【本教程】设置,或者【自行搭建 docker 加速地址】;1、使用 Docker 方式:复制 “2025 年 1 月 2 日更新” 内容中的第④个步骤生成的 Docker 运行命令:docker run -d --restart unless-stopped --net=host --privileged=true --name allinone youshandefeiyang/allinone部署 watchtower 自动监听肥羊 IPTV 的 allinone 镜像更新:docker run -d --name watchtower --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower allinone -c --schedule "0 0 2 * * *"2、使用 Docker compose 方式(复制 “2025 年 1 月 2 日更新” 内容中的第④个步骤生成的 Docker compose 文件内容:):version: "3.3" services: allinone: restart: unless-stopped privileged: true container_name: allinone image: youshandefeiyang/allinone network_mode: "host"二、肥羊 IPTV 的 allinone 的 m3u 链接地址:如果你是在公网服务器部署,不愿意开启聚合TV直播服务,在运行裸程序或者Docker时,加上参数 -tv=false 即可不开启直播服务(仅对gaoma、itv、rptv生效,migu走的是302重定向,没有代理流量)如果你的allinone服务被部署至服务器上,并且使用https域名反代了IP+端口,那么你的链接要变成:https://你的反代域名/tv.m3u(?url=https://你的反代域名)括号中为可选参数,用来方便替换列表前缀为https的,如果反代域名中含有特殊符号的,先去urlencode,如果反代后的域名依旧存在端口,那就把端口照样加上去,比如url=https://feiyang.com:12345,不加url参数默认是http协议举个例子:https://www.feiyang.com/tv.m3u?url=https://www.feiyang.com 1、Ysptp 和 IPtv 聚合 m3u 地址:http://你的IP:35455/tv.m3u2、BiliBili 生活:http:// 你的IP:35455:35455/bililive.m3u3、虎牙一起看:http://你的IP:35455:35455/huyayqk.m3u4、斗鱼一起看:http://你的IP:35455:35455/douyuyqk.m3u5、YY 轮播:http://你的IP:35455:35455/yylunbo.m3u三、代理播放地址抖音:默认最高画质,浏览器打开并复制(live.douyin.com/)xxxxxx,只需要复制后面的xxxxx即可(可选flv和hls两种种流媒体传输方式,默认flv):http://你的IP:35455/douyin/xxxxx(?stream=hls)斗鱼:可选m3u8和flv以及xs三种流媒体传输方式【(www.douyu.com/)xxxxxx 或 (www.douyu.com/xx/xx?rid=)xxxxxx,默认flv】:http://你的IP:35455/douyu/xxxxx(?stream=flv)BiliBili(live.bilibili.com/)xxxxxx:1,平台platform参数选择(默认web,如果有问题,可以切换h5平台): "flv" => "FLV""hls" => "M3U8"2,线路line参数选择(默认线路二,如果卡顿/看不了,请切换线路一或者三,一般直播间只会提供两条线路,所以建议线路一/二之间切换): "first" => "线路一""second" => "线路二" "third" => "线路三"3,画质quality参数选择(默认原画,可以看什么画质去直播间看看,能选什么画质就能加什么参数,参数错误一定不能播放): "4" => "原画质""3" => "低画质"4,最后的代理链接示例:http://你的IP:35455/bilibili/xxxxxx(?platform=hls&line=first&quality=4)虎牙(huya.com/)xxxxxx:1,查看可用CDN:http://你的IP:35455/huya/xxxxx?type=json2,切换媒体类型(默认flv,可选flv、hls):http://你的IP:35455/huya/xxxxx?media=hls3,切换CDN(默认hwcdn,可选hycdn、alicdn、txcdn、hwcdn、hscdn、wscdn,具体可先访问1获取):http://你的IP:35455/huya/xxxxx?cdn=alicdn4,最后的代理链接示例:http://你的IP:35455/huya/xxxxx(?media=xxx&cdn=xxx)YouTube:https://www.youtube.com/watch?v=cK4LemjoFd0 Rid: cK4LemjoFd0http://你的IP:35455/youtube/cK4LemjoFd0(?quality=1080/720...)YY(默认最高画质,参数为4):https://www.yy.com/xxxxhttp://你的IP:35455/yy/xxxx(?quality=1/2/3/4...)四、使用方法:上述 m3u 地址可以在电脑上使用 PotPlayer 打开,或者在 emby/jellyfin/kodi 等多媒体软件中添加到 iptv 插件中使用。
2025年01月12日
81 阅读
0 评论
0 点赞
2025-01-06
十分钟搭建属于自己的信息流—FreshRSS
十分钟搭建属于自己的信息流—FreshRSS原文地址:https://blog.laoda.de/archives/docker-compose-install-freshrss1. 前言为什么要用 RSS?因为它们提供了一种可定制的、无算法的方式来聚合和访问来自多个来源的内容,使我们能够高效管理信息过载,并在不受社交媒体干扰的情况下保持对自己感兴趣内容的更新。2. 介绍这一期我们来介绍另一个和 TinytinyRSS 类似的 RSS 管理服务——FreshRSS。相较于 Tiny Tiny RSS,它有着更低的资源使用、更现代和用户友好的界面,以及更好的文档,使得对于技术能力较弱的用户来说,设置和维护更加容易。3. 相关地址官方 GitHub 地址:https://github.com/FreshRSS/FreshRSS (目前 9.2k 个 star,欢迎大家去给项目点星星!)4. 搭建环境服务器:建议服务器内存 1G 以上系统:Debian 11安装好 Docker、Docker-compose【必需】域名一枚,并做好解析到服务器上【非必需】提前安装好宝塔面板海外版本 aapanel,并安装好 Nginx5. 搭建方式5.1 安装 Docker5.2 创建安装目录创建一下安装的目录:sudo -i mkdir -p /root/data/docker_data/freshrss cd /root/data/docker_data/freshrss接着我们来编辑下docker-compose.ymlvim docker-compose.ymlservices: freshrss: image: freshrss/freshrss:latest container_name: freshrss environment: - CRON_MIN=*/20 #每20分钟刷新一次 - TZ=Asia/Shanghai volumes: - ./data:/var/www/FreshRSS/data - ./extensions:/var/www/FreshRSS/extensions ports: - 8080:80 #左边的8080可以改成服务器上没有用过的端口 depends_on: - postgres restart: always postgres: image: postgres:alpine container_name: freshrss-postgres environment: - POSTGRES_USER=freshrss - POSTGRES_PASSWORD=freshrss #密码可以自己修改 - POSTGRES_DB=freshrss volumes: - ./freshrss-postgres-data:/var/lib/postgresql/data restart: always同样,修改完成之后,可以在英文输入法下,按 i 修改,完成之后,按一下 esc,然后 :wq 保存退出。5.3 打开服务器防火墙(非必需)并访问网页打开防火墙的端口 8080如果你在 docker-compose 文件里换了 9009,这边就需要填 9009,以此类推查看端口是否被占用(以 8080 为例),输入:lsof -i:8080 #查看 8080 端口是否被占用,如果被占用,重新自定义一个端口如果啥也没出现,表示端口未被占用,我们可以继续下面的操作了~如果出现:-bash: lsof: command not found运行:apt install lsof #安装 lsof如果端口没有被占用(被占用了就修改一下端口,比如改成 8381,注意 docker 命令行里和防火墙都要改)5.4 启动 freshrsscd /root/data/docker_data/freshrss docker compose up -d # 注意,老版本用户用 docker-compose up -d等待拉取好镜像,出现 done的字样之后,理论上我们就可以输入 http://ip:8080 访问了。但是这边我们推荐先搞一下反向代理!做反向代理前,你需要一个域名!6. 利用宝塔面板反向代理发现还是有不少小伙伴习惯用宝塔面板,这边也贴一个宝塔面板的反代配置:直接新建一个站点,不要数据库,不要 php,纯静态即可然后打开下面的配置,修改 Nginx 的配置。代码如下:location / { proxy_pass http://127.0.0.1:8080/; # 注意改成你实际使用的端口 rewrite ^/(.*)$ /$1 break; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade-Insecure-Requests 1; proxy_set_header X-Forwarded-Proto https; }7. 使用教程建议参考官方配置文档:https://github.com/freshrssapp/freshrss/blob/main/docs/configuration.md7.1 安装与配置数据库信息主机记得填postgres,其他的按docker-compose.yaml里面的填设置账号密码:安装成功!登录默认订阅了 Fresh RSS 的官方 GitHub 仓库的 releases这边我们不管,先来订阅一下咕咕的博客,最近视频更新进度缓慢,但是博客还是会经常更新的,订阅了博客的 RSS 之后,只要我一更新博客,你就能第一时间看到啦!以咕咕的博客为例子,添加博客的 RSS:https://blog.laoda.de/rss.xml“订阅管理”——“添加订阅源或分类”可以先给分类起个名字,比如 “个人博客”然后再次点击 “添加订阅源”输入咕咕博客的 RSS:https://blog.laoda.de/rss.xml点击左上角 FreshRSS 的图片,就能回到首页了,可以看到已经订阅成功!7.2 扩展下载FreshRSS 还有很多扩展可以下载,你可以选择合适的扩展进行下载。有一个吐槽的点是,这个下载是要手动的...扩展的 GitHub 仓库:https://github.com/FreshRSS/Extensions扩展的下载地址:https://github.com/FreshRSS/Extensions/archive/master.zip基本上就是这个包,我们上传到服务器里。(当然你可以直接用服务器来下载,这样就省得上传这个步骤了)7.2.1 直接命令行操作(二选一)cd /root/data/docker_data/freshrss/extensions/ wget https://github.com/FreshRSS/Extensions/archive/master.zip unzip master.zip cd Extensions-master mv /root/data/docker_data/freshrss/extensions/Extensions-master/* /root/data/docker_data/freshrss/extensions/然后记得重启一下容器:cd /root/data/docker_data/freshrss docker compose down docker compose up -d7.2.2 如果你用的是 finalshell 的话(二选一)上传插件使用 unzip 命令来解压缩,移动到我们制定的文件夹里mv /root/data/docker_data/freshrss/extensions/Extensions-master/* /root/data/docker_data/freshrss/extensions/刷新7.3 配置 API允许手机访问,设置一个 API 密码,手机端,IOS 推荐用 Reeder,安卓推荐 Read You注意手机 app 登录的时候,末尾还要加上greader.php比如:https://xxxxx.com/api/greader.php7.4 更新 freshrsscd /root/data/docker_data/freshrss docker-compose pull docker-compose up -d # 请不要使用 docker-compose stop 来停止容器,因为这么做需要额外的时间等待容器停止;docker-compose up -d 直接升级容器时会自动停止并立刻重建新的容器,完全没有必要浪费那些时间。 docker image prune # prune 命令用来删除不再使用的 docker 对象。删除所有未被 tag 标记和未被容器使用的镜像提示:WARNING! This will remove all dangling images. Are you sure you want to continue? [y/N]输入 y利用 Docker 搭建的应用,更新非常容易~7.5 卸载 freshrss同样进入安装页面,先停止所有容器。cd /root/data/docker_data/freshrss docker-compose down cd .. rm -rf /root/data/docker_data/freshrss # 完全删除可以卸载得很干净。参考资料官方 GitHub:https://github.com/FreshRSS/FreshRSS
2025年01月06日
14 阅读
0 评论
0 点赞
2024-12-02
使用Watchtower自动更新Docker镜像
使用Watchtower自动更新Docker镜像使用 Docker 可以迅速在 VPS 上运行服务,而不用配置和修改环境。Docker 服务的更新通过拉取最新镜像实现,当运行的 Docker 数目多了之后,保持镜像最新就成为了一项琐碎的工作。使用 Watchtower 可以便捷地监控 Docker 服务是否有最新镜像,自动拉取最新镜像、更新服务并删除旧有镜像。Docker compose 是用于定义和运行多容器 Docker 应用程序的工具。在配置好 docker-compose.yml 文件后,使用 docker compose up -d 即可方便上线服务,我的全部 Docker 服务都使用这一方式部署。以下是 Watchtower 的 docker-compose.yml 文件设置。Docker Compose 文件version: "3.3" services: watchtower: image: containrrr/watchtower:latest container_name: watchtower restart: unless-stopped volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - TZ=Asia/Shanghai - WATCHTOWER_DEBUG=true - WATCHTOWER_CLEANUP=true - WATCHTOWER_SCHEDULE=0 0 4 * * ? # - WATCHTOWER_POLL_INTERVAL=43200其中,WATCHTOWER_SCHEDULE 和 WATCHTOWER_POLL_INTERVAL 均为设置 Watchtower 运行频次的指令,两个方式任选一个。前者使用 Cron 格式,在固定时间运行;后者的单位为秒 (S),经过固定时间间隔运行。设置 Watchtower 通知服务Watchtower 使用 Shutrrr 发送通知。以下为设置 Telegram bot 通知:- WATCHTOWER_LIFECYCLE_HOOKS=True - WATCHTOWER_NOTIFICATIONS=shoutrrr - WATCHTOWER_NOTIFICATION_URL=telegram://bot_token@telegram/?channels=user-id通过 @BotFather 创建自己的通知机器人,并获取 bot_token通过 @GetIDs Bot 获取 user-id推荐 IOS 用户使用 Bark 设置通知 [*]:- WATCHTOWER_LIFECYCLE_HOOKS=True - WATCHTOWER_NOTIFICATIONS=shoutrrr - WATCHTOWER_NOTIFICATION_URL=bark://:devicekey@host/path使用邮件通知服务- WATCHTOWER_LIFECYCLE_HOOKS=True - WATCHTOWER_NOTIFICATIONS=email - WATCHTOWER_NOTIFICATION_EMAIL_FROM= #设置通知邮件的发件人 - WATCHTOWER_NOTIFICATION_EMAIL_TO= #设置通知邮件的收件人 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com #SMTP 服务器 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 #SMTP 服务器端口 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER= - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD= - WATCHTOWER_NOTIFICATION_EMAIL_DELAY= #发送通知前的延迟时间,以秒为单位设置部分 Docker 禁止更新1、在不希望被 Watchetower 监控更新的 Docker 容器中添加**环境变量:WATCHTOWER_LABEL_ENABLE=false或者添加容器标签:com.centurylinklabs.watchtower.enable=false2、当无法设置标签时,可以在Watchetower容器中设置环境变量来排除特定的容器,变量填写需要禁止更新的容器名称,用逗号或空格隔开WATCHTOWER_DISABLE_CONTAINERS=测试 Watchtower由于 Watchtower 的默认轮询间隔为 1 小时,因此可能需要等待一段时间才能看到自动更新效果。可以手动触发 Watchtower 的轮询以立即检查是否有更新。可以使用以下命令来手动触发 Watchtowerdocker exec -it watchtower /watchtower --debug --run-once nginx推荐阅读Watchtower 官方手册Watchtower 通过 telegram 发通知
2024年12月02日
107 阅读
0 评论
0 点赞
2024-09-09
自建电子邮件管理程序Cypht
关于CyphtCypht是一款免费开源的Web电子邮件客户端管理程序,它在不牺牲隐私和安全性的前提下,汇聚了个电子邮件账户,让用户仅需一个网页就能轻松管理多个电子邮件账户,包括查看、发送邮件,以及还提供了邮箱常用的过滤、标签、搜索等功能,从而提高了多个邮箱同时使用的效率与便捷。它的亮点特性如下:自托管 :Cypht 支持自托管,你可以选择自己部署服务器,完全掌控自己的数据。端到端加密: 所有通信均在发送者和接收者之间进行加密,即使数据通过不安全的网络,也无需担忧信息泄漏。插件系统 : 通过插件,你可以连接到不同的邮件服务提供商,或扩展其他功能。隐私优先 :Cypht 不存储用户的私钥,确保只有消息的收发双方才能解密信息。它的功能与用途包括:安全的电子邮件: Cypht 提供了一种方法,可以在发送邮件时自动加密消息内容,防止未经授权的第三方阅读。 跨平台 :不论你是 Windows 用户、Mac 用户还是 Linux 爱好者,或者更倾向于使用智能手机,Cypht 都可以无缝适配你的设备。 易于使用 :尽管加密听起来复杂,但 Cypht 的设计原则之一就是易用性,使得即便是对技术不太了解的用户也能轻松上手。 透明度与审计 :开源代码意味着任何人都可以查看其内部工作原理,增强用户对安全性的信心。Cypht部署需要说明的是,一般涉及到安全方面的Docker容器,基本都会需要稳定的数据库作为支撑,今天介绍的这个Cypht也是一样,所以在部署之前,咱们需要先搞定数据库。第一步:创建数据库先打开数据库管理工具phpMyAdmin,然后在“账户”里面“新增用户账户”。填入新增用户账户的信息:用户名:cypht主机名:任意主机( % )密码:随意(我这里演示就设为了“123456”)然后勾选下面的“创建与用户同名的数据库并授予所有权限”,最后别忘了点页面下方的“执行”按钮第二步:Cypht部署1.任意位置新建文件夹2.新建docker-compose.yaml文件3.复制下面的80端口被占用可改为其他端口version: '3' services: cypht: image: sailfrog/cypht-docker:latest volumes: - ./cypht/users:/var/lib/hm3/users ports: - "80:80" environment: - CYPHT_AUTH_USERNAME=admin - CYPHT_AUTH_PASSWORD=admin_password - CYPHT_DB_CONNECTION_TYPE=host - CYPHT_DB_HOST=172.17.0.1:3306 - CYPHT_DB_HOST=db - CYPHT_DB_NAME=cypht - CYPHT_DB_USER=cypht - CYPHT_DB_PASS=123456 - CYPHT_SESSION_TYPE=DBCYPHT_AUTH_USERNAME 后台管理员账号,自己随意设置CYPHT_AUTH_PASSWORD 后台管理员密码,自己随意设置CYPHT_DB_CONNECTION_TYPE 数据库连接类型,默认为 hostCYPHT_DB_HOST 填写数据库主机地址+端口,默认为 宿主机在Docker内网IP:3306CYPHT_DB_NAME 数据库名称,我前面设置的为cyphtCYPHT_DB_USER 数据库用户,我前面设置的为cyphtCYPHT_DB_PASS 数据库密码,我前面设置的为123456CYPHT_SESSION_TYPE 保持登录状态,默认的 DB 即可cd进docker-compose.yaml文件目录,启动docker-compose up -d宿主机在Docker内网IPdocker在运行时就建立了虚拟网卡,并命名为docker0,在宿主机ifconfig可以看到网桥的ip是172.17.0.1设置宿主机mysql允许docker0的虚拟网卡ip访问宿主机mysql设置允许用户cypht通过172.19.0.2访问cypht数据库的任意表mysql -uroot -pmysql>GRANT ALL PRIVILEGES ON cypht.* TO 'cypht'@'172.19.0.2' IDENTIFIED BY '123456' WITH GRANT OPTION; mysql>flush privileges;Cypht体验直接在浏览器中输入 【 IP:端口号】 就能看到登录界面了首次打开需要登录。登录的账号和密码就是我们部署时环境变量中设置的管理员账号和密码登录成功后的主界面,程序默认为英文界面。不过程序是可以通过如上图所示的操作设置为简体中文的时区默认也不是咱们内地,我们也可以通过设置更改接着咱们先来添加一个邮箱。直接在首页位置点击“添加电子邮件账户”然后输入对应的密码。请注意:如果你的Gmail开启了两步验证,这里的密码是谷歌“应用专用密码”,而不是你实际的谷歌账号密码!!!Gmail应用密码登录进来后就能直接看到自己所有的邮箱信息了可以直接点开邮件,并对邮件进行回复或者转发等操作,和谷歌自己的邮箱操作差不多如果说官方服务列表中没有我们需要的邮箱服务商,我们也可以通过SMTP/IMAP服务器的方式添加,具体的大家自己研究下吧同时,该项目还支持添加 RSS 订阅<u>最后的最后,你的设置变动都需要点击保存,否则下次在别的地方登陆都是没有任何数据的</u>
2024年09月09日
102 阅读
0 评论
0 点赞
2024-08-03
一个Linux服务器WEB SSH面板(webSSH&webSFTP)
[!WARNING]初次部署EasyNode,登录系统后务必记得修改默认账户密码 admin/admin![!WARNING]强烈建议使用 iptables 或 fail2ban 等安全服务限制IP访问,谨慎暴露面板服务到公网。[!NOTE]客户端信息监控与webssh功能都将以该服务器作为中转。中国大陆连接建议使用香港、新加坡、日本、韩国等地区的低延迟服务器来安装服务端功能[ ] webssh终端&SFTP[ ] 批量导入(Xshell&FinalShell)[ ] 实例分组[ ] 凭据托管[ ] 邮件通知[ ] 服务器状态推送[ ] 脚本库[ ] 批量指令[x] 终端自定义安装服务端安装占用端口:8082 推荐使用docker镜像安装Dockerdocker run -d --net=host --name=easynode-server -v $PWD/easynode/db:/easynode/app/db chaoszhu/easynode访问:http://yourip:8082手动部署依赖Nodejs版本 > 20+git clone https://github.com/chaos-zhu/easynode cd easynode yarn cd web yarn build mv dist/* ../server/app/static cd ../server yarn start # 后台运行需安装pm2 pm2 start index.js --name easynode-server访问:http://yourip:8082查看日志:pm2 log easynode-server启动服务:pm2 start easynode-server停止服务:pm2 stop easynode-server删除服务:pm2 delete easynode-server客户端安装客户端用于实时向服务端推送系统、公网IP、CPU、内存、硬盘、网卡等基础信息,不安装不影响使用面板,但是无法实时同步基础信息。占用端口:22022安装curl -o- https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/main/client/easynode-client-install.sh | bash卸载curl -o- https://mirror.ghproxy.com/https://raw.githubusercontent.com/chaos-zhu/easynode/main/client/easynode-client-uninstall.sh | bash查看客户端状态:systemctl status easynode-client查看客户端日志: journalctl --follow -u easynode-client查看详细日志:journalctl -xe--
2024年08月03日
140 阅读
0 评论
1 点赞
2024-07-30
Docker部署搜索工具SearXNG
SearXNG 是用 Python 编写的一款开源搜索工具安装前准备工作SearXNG 文档地址:网页链接Github 开源地址:网页链接Docker 安装教程 (菜鸟教程):网页链接Docker-Compose 安装教程 (菜鸟教程):网页链接文章参考:我不是咕咕鸽大佬的博客安装部署步骤一、创建项目存放路径并克隆源码cd /opt #在opt目录下创建 git clone https://github.com/searxng/searxng-docker.git #克隆源码 mv searxng-docker searxng #强迫症改名步骤二、修改 Docker-Compose 配置文件cd searxng vim docker-compose.yaml将运行 candy 部分注释掉,因为我们不用 Candy 做反向代理将这里的 IP 地址从 127.0.0.1 改成 0.0.0.0 以便局域网访问,将冒号前面的端口修改成自己服务器上没有被占用的端口编辑环境配置vim .env将域名修改成自己准备好的域名步骤三、编辑容器配置文件cd searxng生成密钥sed -i "s|ultrasecretkey|$(openssl rand -hex 32)|g" settings.yml修改配置文件,取消限制,将 limter 改成 false步骤四、启动容器cd /opt/searxng docker-compose up -d步骤五、开启宝塔面板反向代理将反向代理配置部分修改如下location ^~ { proxy_pass http://127.0.0.1:自定义的端口; proxy_set_header Host $host; proxy_set_header Connection $http_connection; proxy_set_header X-Scheme $scheme; proxy_set_header X-Script-Name /searxng; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
2024年07月30日
233 阅读
0 评论
2 点赞
2024-07-30
Docker部署MeloTTS高质量多语言文本转语音(TTS)
MeloTTS:由MyShell AI开发的一个高质量的多语言文本到语音(TTS)库。 支持英语、西班牙语、法语、中文、日语和韩语等多种语言。 速度非常快,支持中英混合的发音,能生成清晰、自然的语音输出。 即使在普通的在CPU上也能实现实时语音合成。主要功能:多语言支持:MeloTTS支持多种语言的文本到语音转换,包括英语(有美国、英国、印度、澳大利亚等多种口音)、西班牙语、法语、中文、日语和韩语。这使得它适用于全球多种语言环境的应用场景。中英混合发音:特别对于中文,MeloTTS支持中英混合的发音,这是在多语言交流中非常实用的功能,能够处理包含英文单词的中文文本。实时CPU推理:MeloTTS设计优化以确保即使在没有GPU加速的情况下,也能在CPU上实现实时语音合成,这提高了其在不同硬件环境下的可用性。高质量语音输出:MeloTTS旨在生成清晰、自然的语音输出,力求在各种支持的语言中保持语音的自然度和清晰度。易于安装和使用:提供了简单的安装指南和Python API,使得用户可以轻松地在Linux环境中安装MeloTTS,并通过几行代码实现文本到语音的转换。Linux and macOS InstallThe repo is developed and tested on Ubuntu 20.04 and Python 3.9.git clone https://github.com/myshell-ai/MeloTTS.git cd MeloTTS pip install -e . python -m unidic downloadDocker InstallBuild Dockergit clone https://github.com/myshell-ai/MeloTTS.git cd MeloTTS docker build -t melotts . Run Dockerdocker run -it -p 8888:8888 melottsIf your local machine has GPU, then you can choose to run:docker run --gpus all -it -p 8888:8888 melottsThen open http://localhost:8888 in your browser to use the app.Python APIfrom melo.api import TTS # Speed is adjustable speed = 1.0 device = 'cpu' # or cuda:0 text = "我最近在学习machine learning,希望能够在未来的artificial intelligence领域有所建树。" model = TTS(language='ZH', device=device) speaker_ids = model.hps.data.spk2id output_path = 'zh.wav' model.tts_to_file(text, speaker_ids['ZH'], output_path, speed=speed)
2024年07月30日
289 阅读
0 评论
1 点赞
2024-07-30
部署changedetection.io,一个网站更改检测、监控和通知的开源工具
官方Github: https://github.com/dgtlmoon/changedetection.ioWeb Site Change Detection, Monitoring and Notification. Live your data-life pro-actively, Detect website changes and perform meaningful actions, trigger notifications via Discord, Email, Slack, Telegram, API calls and many more.网站更改检测、监控和通知。 主动体验您的数据生活,检测网站更改并执行有意义的操作,通过 Discord、电子邮件、Slack、电报、API 调用等触发通知。准备工作Docker 安装教程 (菜鸟教程):网页链接Docker-Compose 安装教程 (菜鸟教程):网页链接宝塔面板,反代环境部署执行以下命令,新建目录mkdir -p /opt/docker/changedetection.io && cd /opt/docker/changedetection.io新建docker-compose.yaml文件然后输入以下配置内容:version: "3" services: changedetection: image: ghcr.io/dgtlmoon/changedetection.io container_name: changedetection hostname: changedetection restart: unless-stopped environment: - USE_X_SETTINGS=1 - BASE_URL=https:// #修改成你的域名 - PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000/ ports: - 20041:5000 #2077为暴露端口,如被占用,请自行更改替换,需要在云服务器的控制台防火墙开放相应端口! volumes: - changedetection-data:/datastore playwright-chrome: image: browserless/chrome hostname: playwright-chrome restart: unless-stopped volumes: changedetection-data:输入执行以下命令后台启动容器docker compose up -d访问 https://ip:20041 进入主页修改网页抓取方式点击SETTINGS,Fetching中的Fetch Method,将其改为Playwright Chromium/Javascript via 'ws://playwright-chrome:3000/',然后Save即可!监控可以改监控间隔,点击 Edit:General: URL: https://api.bilibili.com/x/space/wbi/arc/search?mid=8366990&ps=30&tid=0&pn=1&keyword=&order=pubdate&order_avoided=true&w_rid=b37f7220280dbec445b877940e8bbc36&wts=1671982474 Time Between Check: 0 0 0 5 0 Request: Fetch Method: Basic fast Plaintext/HTTP Client Request method: GET Request headers: { accept: application/json, text/plain, */* accept-encoding: gzip, deflate, br accept-language: zh-CN,zh;q=0.9,en-AS;q=0.8,en;q=0.7 cache-control: no-cache cookie: buvid3=F8D5D1C8-55E2-23AC-AA4B-CD66147A8A0488878infoc; i-wanna-go-back=-1; b_ut=7; _uuid=938E2C3F-2567-F173-BA77-8E34C109BC47888980infoc; buvid_fp=a65c806ec103b5691068a7fe2d31f818; buvid4=891AB099-8FE4-6031-3245-4DCA36CEBFD789604-022051401-sluv7aFmF1Lh17bDnV1PEA%3D%3D; CURRENT_FNVAL=4048; blackside_state=1; PVID=5; b_lsid=F10E97E10F_18549E99616 dnt: 1 origin: https://space.bilibili.com pragma: no-cache referer: https://space.bilibili.com/8366990/video sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "macOS" sec-fetch-dest: empty sec-fetch-mode: cors sec-fetch-site: same-site user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 } Filters & Triggers: CSS/JSONPath/JQ/XPath Filters: json:$.data.list.vlist[0].[title] Notifications: tgram://5705562690:AAasdasddbaInDL0lHh8bcab-A7O4BpWv9_gvfE/2053317177/最新案例:想象一下,你想添加你最喜欢的网站 Opensource.com 进行监控。你只想知道主要标注文章何时包含 “python” 一词,并且通过 Matrix 收到通知。要做到这点,首先要使用“视觉选择器Visual Filter Selector”工具。(这需要连接 playwright 浏览器界面)。该工具会自动计算出针对内容的最佳 Xpath 或 CSS 过滤器。否则,你会从每天的页面更新中得到大量的噪音。接下来,访问“Filters & Triggers”标签。在 “CSS/JSON/XPATH Filter”区域(蓝色圆圈),你可以看到上一步自动生成的 CSS 过滤器。有几个有用的过滤器,比如“Remove elements”(适合移除嘈杂的元素)、“忽略文本Ignore text”、“触发/等待文本Trigger/wait for text”,和“如果文本匹配则阻止变化检测Block change-detection if text matches”(用于等待一些文本消失,如“售罄”)。在“触发/等待文本Trigger/wait for text”(红色圆圈)中,输入你想监测的关键词。(在这个例子中是 “python”)。最后一步是在“通知Notifications”选项卡中,你要在那里配置你想收到的通知。下面我使用邮箱、telegram添加了一个 通知目标。JSON API 监控案例找一个天气预报的 JSON API,请求是restfull 风格,city_code 为 9 位数字。只要拼接在地址 “http://t.weather.itboy.net/api/weather/city/+city_code” 后面即可。city_code 可以在这里查询: https://github.com/baichengzhou/weather.api/blob/master/src/main/resources/citycode-2019-08-23.json比如上海的 city_code 为 101020100所以在浏览器中输入 http://t.weather.itboy.net/api/weather/city/101020100 就能看到上海的天气信息将网页上的文本全部复制(Ctrl+A 然后 Ctrl+C),接着打开网页:https://jsonpath.com这个网址可用于 JSON 的语法测试将前面复制的内容粘贴到左侧的 Inputs,因为希望返回所有的数据,所以在 JSONPath Syntax 中输入了 $右侧的 Evaluation Results 不仅返回了所有的数据,并且对 JSON 数据进行了格式化处理,更易于阅读如果只是需要获取温度,可以在 JSONPath Syntax 中输入 $.data.wendu准备工作到这里就差不多了,返回到 Changedetection 新增一个监控,分别填入下面的内容后,点 Watch网址:http://t.weather.itboy.net/api/weather/city/101020100tag:天气在 CSS/JSON Filter 中输入 json:$.data.wendu,其中前缀 json: 是必须要的通知邮箱推送点右上角的 SETTINGS 是 default global settings,只需要在 Notification URL List 中设置通知方式Changedetection 采用了 apprise 项目来实现 通知 功能,可惜除了 邮件 ,老苏没找到手机上已经安装的应用所有支持的通知方式都在这里:https://github.com/caronc/apprise邮件发送的 URL 地址是
2024年07月30日
254 阅读
0 评论
0 点赞
2024-06-27
国内无法访问下载 Docker 镜像的多种解决方案
简介2023 年 5 月, hub.docker.com "不知" 何种原因国内均无法正常访问了。当时只是官网不能访问,但不影响 pull 镜像。2024年6月7日,GFW正式DNS污染+SNI阻断了docker.com及其相关域名。从国内解析得到的IP地址为Twitter/Facebook的IP,符合大墙DNS污染的特征。而如果使用海外解析得到的正常IP地址从国内访问则会被SNI重置阻断链接。2024 年 6 月,国内几家 Docker Hub 镜像服务平台均发公告说 "被" 要求下架,停止服务。不知以后是否开放?或开启白名单模式?与此同时,上交镜像站等一系列中国大陆公益镜像站点也“接上级主管部门通知,暂时关闭 Docker Hub 镜像缓存服务”。(通知链接 1 2)更新:南京大学、中科大、上海交大 目前明确停止docker镜像 网易之前死了 腾讯微软据说内网可用 阿里登陆后就可以拿到子域名 百度好像也挂了 dockerproxy被墙这里不讨论其原因!这里分享几个便捷方法,帮助有需求的朋友正常的拉取 Docker 镜像!零门槛境外镜像优点:不需大量修改,只需几个命令缺点:网络可能慢或者不稳定下面命令可直接执行~sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://docker.m.daocloud.io", "https://huecker.io", "https://dockerhub.timeweb.cloud", "https://noohub.ru" ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker命令行执行 docker info,如果从结果中看到了如下内容,说明配置成功。Registry Mirrors: [...] https://docker.m.daocloud.ioDocker Hub 镜像加速器列表以下镜像站来源于互联网(感谢热心网友),可能出现宕机、转内网、关停等情况,建议同时配置多个镜像源。2024年6月27日 亲测可用镜像加速器地址其他说明https://dockerpull.comCF的workers来搭建https://dockerproxy.cnCF的workers来搭建https://docker.1panel.live1Panel 面板提供(推荐)https://hub.rat.dev耗子面板提供https://docker.chenby.cnDocker Hubhttps://docker.anyhub.us.kgDockerHub 镜像加速代理https://dockerhub.icuDocker镜像加速站https://docker.ckyl.meDocker镜像加速站https://dockerhub.jobcher.comDocker Hubhttps://docker.hpcloud.cloud镜像使用说明https://docker.awsl9527.cn镜像使用说明https://www.hallodocker.com/镜像使用说明Yandex 容器加速优点:适合单独 pull 镜像使用,俄罗斯大厂提供服务缺点:不支持配置到 daemon.json官方镜像:https://mirror.yandex.ru/使用方式:docker pull cr.yandex/mirror/nginx低门槛Docker 使用 HTTP 代理优点:可从 Docker 官方直接拉取这里主要介绍如何让服务器的 Docker Pull 的时候能走代理!1,新建目录mkdir -p /etc/systemd/system/docker.service.d2,新建文件,粘贴并内容,并保存!vim /etc/systemd/system/docker.service.d/http-proxy.conf以下粘贴内容,IP 一定要换成你代理软件运行的电脑的内网 IP,通过 ipconfig 可以查看端口一定要是代理软件设置的局域网端口![Service] Environment="HTTP_PROXY=http://USERNAME:PASSWORD@[your.proxy.server]:[port]" Environment="HTTPS_PROXY=http://USERNAME:PASSWORD@[your.proxy.server]:[port]0" Environment="NO_PROXY=localhost,127.0.0.1,.example.com"3,重启 Dockersystemctl daemon-reload systemctl restart docker4,检查环境变量是否生效systemctl show --property=Environment docker高门槛Cloudflare 反向代理优点:只需有 CF 账号就行,自己专属,不用自己签发证书缺点:CF 在国内有 DNS 污染,可能无法正常访问简要步骤:1,登录到 CFhttps://dash.cloudflare.com/2,创建Workers控制台面板 -> 左侧 Workers 和 Pages -> 创建应用程序 -> 创建 Worker -> 点击保存 -> 点击完成 -> 编辑代码worker.js 内容 // _worker.js // Docker镜像仓库主机地址 let hub_host = 'registry-1.docker.io'; // Docker认证服务器地址 const auth_url = 'https://auth.docker.io'; // 自定义的工作服务器地址 let workers_url = 'https://hub.ixm.pw/'; let 屏蔽爬虫UA = ['netcraft']; // 根据主机名选择对应的上游地址 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", "nvcr": "nvcr.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="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> ` return text; } async function searchInterface() { const text = ` <!DOCTYPE html> <html> <head> <title>Docker Hub Search</title> <style> body { font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; background: linear-gradient(to right, rgb(28, 143, 237), rgb(29, 99, 237)); } .logo { margin-bottom: 20px; } .search-container { display: flex; align-items: center; } #search-input { padding: 10px; font-size: 16px; border: 1px solid #ddd; border-radius: 4px; width: 300px; margin-right: 10px; } #search-button { padding: 10px; background-color: rgba(255, 255, 255, 0.2); /* 设置白色,透明度为10% */ border: none; border-radius: 4px; cursor: pointer; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; } #search-button svg { width: 24px; height: 24px; } </style> </head> <body> <div class="logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 18" fill="#ffffff" width="100" height="75"> <path d="M23.763 6.886c-.065-.053-.673-.512-1.954-.512-.32 0-.659.03-1.01.087-.248-1.703-1.651-2.533-1.716-2.57l-.345-.2-.227.328a4.596 4.596 0 0 0-.611 1.433c-.23.972-.09 1.884.403 2.666-.596.331-1.546.418-1.744.42H.752a.753.753 0 0 0-.75.749c-.007 1.456.233 2.864.692 4.07.545 1.43 1.355 2.483 2.409 3.13 1.181.725 3.104 1.14 5.276 1.14 1.016 0 2.03-.092 2.93-.266 1.417-.273 2.705-.742 3.826-1.391a10.497 10.497 0 0 0 2.61-2.14c1.252-1.42 1.998-3.005 2.553-4.408.075.003.148.005.221.005 1.371 0 2.215-.55 2.68-1.01.505-.5.685-.998.704-1.053L24 7.076l-.237-.19Z"></path> <path d="M2.216 8.075h2.119a.186.186 0 0 0 .185-.186V6a.186.186 0 0 0-.185-.186H2.216A.186.186 0 0 0 2.031 6v1.89c0 .103.083.186.185.186Zm2.92 0h2.118a.185.185 0 0 0 .185-.186V6a.185.185 0 0 0-.185-.186H5.136A.185.185 0 0 0 4.95 6v1.89c0 .103.083.186.186.186Zm2.964 0h2.118a.186.186 0 0 0 .185-.186V6a.186.186 0 0 0-.185-.186H8.1A.185.185 0 0 0 7.914 6v1.89c0 .103.083.186.186.186Zm2.928 0h2.119a.185.185 0 0 0 .185-.186V6a.185.185 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm-5.892-2.72h2.118a.185.185 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186H5.136a.186.186 0 0 0-.186.186v1.89c0 .103.083.186.186.186Zm2.964 0h2.118a.186.186 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186H8.1a.186.186 0 0 0-.186.186v1.89c0 .103.083.186.186.186Zm2.928 0h2.119a.185.185 0 0 0 .185-.186V3.28a.186.186 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm0-2.72h2.119a.186.186 0 0 0 .185-.186V.56a.185.185 0 0 0-.185-.186h-2.119a.186.186 0 0 0-.185.186v1.89c0 .103.083.186.185.186Zm2.955 5.44h2.118a.185.185 0 0 0 .186-.186V6a.185.185 0 0 0-.186-.186h-2.118a.185.185 0 0 0-.185.186v1.89c0 .103.083.186.185.186Z"></path> </svg> </div> <div class="search-container"> <input type="text" id="search-input" placeholder="Search Docker Hub"> <button id="search-button"> <svg focusable="false" aria-hidden="true" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M21 21L16.65 16.65M19 11C19 15.4183 15.4183 19 11 19C6.58172 19 3 15.4183 3 11C3 6.58172 6.58172 3 11 3C15.4183 3 19 6.58172 19 11Z" stroke="white" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> </svg> </button> </div> <script> function performSearch() { const query = document.getElementById('search-input').value; if (query) { window.location.href = '/search?q=' + encodeURIComponent(query); } } document.getElementById('search-button').addEventListener('click', performSearch); document.getElementById('search-input').addEventListener('keypress', function(event) { if (event.key === 'Enter') { performSearch(); } }); </script> </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 const userAgentHeader = request.headers.get('User-Agent'); const userAgent = userAgentHeader ? userAgentHeader.toLowerCase() : "null"; if (env.UA) 屏蔽爬虫UA = 屏蔽爬虫UA.concat(await ADD(env.UA)); workers_url = `https://${url.hostname}`; const pathname = url.pathname; // 获取请求参数中的 ns const ns = url.searchParams.get('ns'); const hostname = url.searchParams.get('hubhost') || url.hostname; const hostTop = hostname.split('.')[0]; // 获取主机名的第一部分 let checkHost; // 在这里定义 checkHost 变量 // 如果存在 ns 参数,优先使用它来确定 hub_host if (ns) { if (ns === 'docker.io') { hub_host = 'registry-1.docker.io'; // 设置上游地址为 registry-1.docker.io } else { hub_host = ns; // 直接使用 ns 作为 hub_host } } else { checkHost = routeByHosts(hostTop); hub_host = checkHost[0]; // 获取上游地址 } const fakePage = checkHost ? checkHost[1] : false; // 确保 fakePage 不为 undefined console.log(`域名头部: ${hostTop}\n反代地址: ${hub_host}\n伪装首页: ${fakePage}`); const isUuid = isUUID(pathname.split('/')[1].split('/')[0]); if (屏蔽爬虫UA.some(fxxk => userAgent.includes(fxxk)) && 屏蔽爬虫UA.length > 0) { // 首页改成一个nginx伪装页 return new Response(await nginx(), { headers: { 'Content-Type': 'text/html; charset=UTF-8', }, }); } 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)); } else if (url.pathname == '/'){ return new Response(await searchInterface(), { headers: { 'Content-Type': 'text/html; charset=UTF-8', }, }); } 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 ( hub_host == 'registry-1.docker.io' && /^\/v2\/[^/]+\/[^/]+\/[^/]+$/.test(url.pathname) && !/^\/v2\/library/.test(url.pathname)) { //url.pathname = url.pathname.replace(/\/v2\//, '/v2/library/'); url.pathname = '/v2/library/' + url.pathname.split('/v2/')[1]; 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 }); } async function ADD(envadd) { var addtext = envadd.replace(/[ |"'\r\n]+/g, ',').replace(/,+/g, ','); // 将空格、双引号、单引号和换行符替换为逗号 if (addtext.charAt(0) == ',') addtext = addtext.slice(1); if (addtext.charAt(addtext.length - 1) == ',') addtext = addtext.slice(0, addtext.length - 1); const add = addtext.split(','); return add; }修改自定义域名 需要是托管dns在cloudflare的域名才可以3,点击部署即可,右上角 deploy保存4,绑定自定义域名设置 -> 触发器 -> 自定义域 -> 点击【添加自定义域】这里添加上自定义域名 [假如我的是mirrors.dockerpull.com]保存 大功告成 现在可以用这个自定义的域名访问了演示地址:dockerhub.o0o.us.kg接下来还有可以选择开启的环境变量功能 就是伪装首页变量说明变量名示例备注URL302https://baidu.com主页302跳转URLhttps://dockerpull.com 121主页伪装(设为nginx则伪装为nginx默认页面)如果你像我的dockerpull.com 40无所畏惧 就可以不管 如果你想自己稳定使用 不想公开的话 可以设置伪装页面 找到设置 环境变量如果想别人访问域名首页的时候重定向到别的网站 可以加入环境变量URL302必须要大写的哈 然后值填写需要目标域名 我以跳转到百度为例保存之后 访问首页就会自动跳转到百度 但是拉取docker镜像的时候 不会受到影响第二种 是伪装首页 可以伪装成任意的网页首页 变量名称改为URL 也是要大写 值输入https://dockerpull.com 保存这时候访问域名 就会出现我的那个镜像站的页面,当然也可以用别的页面使用服务器自建优点:需要有境外服务器缺点:网络可能慢或者不稳定这种方法需要自己有一台境外服务器,签发域名证书。按下面配置即可!工作原理当您首次从本地注册表镜像请求图像时,它会从公共Docker注册表中拉取图像,并在将其返回给您之前将其存储在本地。在后续的请求中,本地注册表镜像可以从自己的存储中提供图像。前期准备1.一个没有被墙的、延迟和带宽较好的非大陆小鸡(墙了的话可以试试套cf)2.一个域名,无需备案,解析到你的小鸡的ip上,申请好证书,后续反代需要3.安装好了docker及docker-composedocker安装docker-compose安装首先创建一个docker-compose文件vi registry/docker-compose.yml然后粘贴如下内容#version: '3' #最新版本docker 不在需要此字段 services: registry: image: registry:2 ports: - "15000:5000" environment: REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io # 上游源 REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR: inmemory # 内存缓存 volumes: - ./data:/var/lib/registry使用docker-compose命令一键启动docker-compose up -d反向代理需要注意的是如果仅仅作为镜像源,需要把push功能ban掉,推荐使用nginx反代的时候禁止其他http method# 端口, 域名 都改为自己的 server { listen 80; server_name my-registry-domain.com; location / { # 仅允许 GET 请求 limit_except GET { deny all; } proxy_pass http://localhost:15000; # 假设 Docker Registry 运行在本地的 15000 端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }项目脚本部署GitHub项目地址:https://github.com/dqzboy/Docker-Proxy一键脚本执行✨️ 一键部署Docker镜像代理服务的功能,支持基于官方Docker Registry的镜像代理.✨️ 支持多个镜像仓库的代理,包括Docker Hub、GitHub Container Registry (ghcr.io)、Quay Container Registry (quay.io)和 Kubernetes Container Registry (k8s.gcr.io)✨️ 自动检查并安装所需的依赖软件,如Docker、Nginx等,并确保系统环境满足运行要求.✨️ 自动清理注册表上传目录中的那些不再被任何镜像或清单引用的文件✨️ 提供了重启服务、更新服务、更新配置和卸载服务的功能,方便用户进行日常管理和维护✨️ 支持主流Linux发行版操作系统,例如centos、Ubuntu、Rocky、Debian、Rhel等✨️ 支持主流ARCH架构下部署,包括linux/amd64、linux/arm64# CentOS yum -y install wget curl # ubuntu apt -y install wget curl bash -c "$(curl -fsSL https://raw.githubusercontent.com/dqzboy/Docker-Proxy/main/install/DockerProxy_Install.sh)"配置nginx反向代理### docker hub 51000 ### gchr 52000 ### gcr 53000 ### k8s-gcr 54000 ### quay 55000 location ^~ / { proxy_pass http://127.0.0.1:51000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; add_header X-Cache $upstream_cache_status; add_header Strict-Transport-Security "max-age=31536000"; }直接nginx反代这里博主并未测试,下面内容仅供参考# 使用 map 来匹配和替换 upstream 头部中的 auth.docker.io map $upstream_http_www_authenticate $m_www_authenticate_replaced { "~auth\.docker\.io(.*)" "$1"; default ""; } map $m_www_authenticate_replaced $m_final_replaced { "~(.*)" 'Bearer realm=\"$scheme://$host$1'; default ""; } server { listen 80; listen 443 ssl http2; server_name 域名; #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则 #error_page 404/404.html; ssl_certificate 证书地址; ssl_certificate_key 秘钥地址; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000"; error_page 497 https://$host$request_uri; #SSL-END proxy_ssl_server_name on; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 修改jwt授权地址 proxy_hide_header www-authenticate; add_header www-authenticate "$m_final_replaced" always; # 关闭缓存 proxy_buffering off; # 转发认证相关 proxy_set_header Authorization $http_authorization; proxy_pass_header Authorization; # 对 upstream 状态码检查,实现 error_page 错误重定向 proxy_intercept_errors on; recursive_error_pages on; # 根据状态码执行对应操作,以下为301、302、307状态码都会触发 error_page 301 302 307 = @handle_redirect; # v1 api location /v1 { proxy_pass https://index.docker.io; proxy_set_header Host index.docker.io; } # v2 api location /v2 { proxy_pass https://index.docker.io; proxy_set_header Host index.docker.io; } # jwt授权地址 location /token { proxy_pass https://auth.docker.io; proxy_set_header Host auth.docker.io; } location / { # Docker hub 的官方镜像仓库 proxy_pass https://registry-1.docker.io; proxy_set_header Host registry-1.docker.io; } location @handle_redirect { resolver 1.1.1.1; set $saved_redirect_location '$upstream_http_location'; proxy_pass $saved_redirect_location; }其他开源项目https://github.com/NoCLin/LightMirrorshttps://github.com/bboysoulcn/registry-mirror最后总结1,如临时使用,建议参与零门槛几个方案,方便快捷2,据说后面 pip 源可能也会受到影响,可用采用 HTTP 代理方式
2024年06月27日
1,862 阅读
0 评论
2 点赞
2023-11-28
解决Docker容器 iptables问题
一、问题现象最近在研究Docker容器日志管理时,启动容器出现iptables相关报错,具体问题如下运行容器[root@node-11 ~]# docker run -d -p 24224:24224 -p 24224:24224/udp -v /data:/fluentd/log fluent/fluentd出现如下报错docker: Error response from daemon: driver failed programming external connectivity on endpoint quizzical_thompson (c2b238f6b003b1f789c989db0d789b4bf3284ff61152ba40dacd0e01bd984653): (iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.3 --dport 24224 -j ACCEPT: iptables: No chain/target/match by that name. (exit status 1)).二、解决办法经过查阅资料得知是docker0网桥的原因,解决上面报错问题需要进行一下步骤1.kill掉docker所有进程[root@node-11 ~]# pkill docker 2.清空nat表的所有链[root@node-11 ~]# iptables -t nat -F3.停止docker默认网桥docker0[root@node-11 ~]# ifconfig docker0 down4.删除docker0网桥apt install bridge-utils brctl delbr docker05.重启docker服务[root@node-11 ~]# systemctl restart docker至此,成功运行docker容器[root@node-11 ~]# docker run -d -p 24224:24224 -p 24224:24224/udp -v /data:/fluentd/log fluent/fluentd 644e43d03b9a2b30c062c8b5cde972b5514e6eef8a8ae95a6ab8c8004af6db5b
2023年11月28日
152 阅读
0 评论
2 点赞
1
2