首页
关于
Search
1
AdGuardHome 安装及部署教程
37,851 阅读
2
搭建基于telegram的无限网盘
9,557 阅读
3
最新Cloudflare免费自选IP教程(非Partner)
8,885 阅读
4
关于微软Azure学生白嫖指南
8,636 阅读
5
Oracle开放全部端口并关闭防火墙
8,544 阅读
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
登录
Search
标签搜索
docker
张至顺
金刚长寿功
PT
qBittorrent
onedrive
telegram
图床
青龙
内网穿透
一键
签到框架
目录列表
onedrive第三方
直链解析
searx
自建搜索引擎
python3
centos7
Transmission
myedunote
累计撰写
84
篇文章
累计收到
1
条评论
首页
栏目
默认分类
技术搬砖
教学设计
故事奇谈
生活琐事
错题分析
精品软件
页面
关于
搜索到
84
篇与
admin
的结果
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://你的域名' // 根据主机名选择对应的上游地址 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="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 ; } 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 }) }修改自定义域名 需要是托管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.一个没有被墙的、延迟和带宽较好的非大陆小鸡
2024年06月27日
190 阅读
0 评论
0 点赞
2024-03-12
OVH Cloud 服务器配置 IPV6 地址
前言前段时间黑五的时候入手了一款年付17.88美元的OVH服务器,最近才发现后台分配了IPV6地址,但机器上默认并没有配置上IPV6连接,原来需要自己手动配置,这里就记录下如何给OVH的机器配置IPV6连接;开始在 OVH 的后台可以看到分配的 IPV6 地址及网关; 然后用 SSH 工具连接上服务器后开始配置;方法一方法一为临时配置,重启后失效 用root用户依次运行以下命令:ip addr add IPV6地址/64 dev ens3 ip -6 route add IPV6网关 dev ens3 ip -6 route add default via IPV6网关 dev ens3注意:将命令中的IPV6地址和IPV6网关替换成你自己后台分配的地址及网关方法二此方法配置后重启不会失效,永久有效,不支持Ubuntu18.04 编辑/etc/network/interfaces文件vi /etc/network/interfaces将以下代码添加到文件中iface ens3 inet6 static address IPV6地址 netmask 64 gateway IPV6网关 autoconf 0注意:将命令中的IPV6地址和IPV6网关替换成你自己后台分配的地址及网关 添加完成后保存退出,然后重启网络配置使其生效即可/etc/init.d/networking restart测试IPV6 测试命令ping6 ipv6.google.com # 或者 ping6 ipv6.baidu.com # 测试结果 root@sunpma:~# ping6 ipv6.google.com PING ipv6.google.com(lga25s62-in-x0e.1e100.net) 56 data bytes 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=2 ttl=48 time=6.82 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=3 ttl=48 time=6.81 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=4 ttl=48 time=6.72 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=5 ttl=48 time=6.78 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=6 ttl=48 time=6.80 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=7 ttl=48 time=6.72 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=8 ttl=48 time=6.78 ms 64 bytes from lga25s62-in-x0e.1e100.net: icmp_seq=9 ttl=48 time=6.86 ms一键脚本测试: *
2024年03月12日
83 阅读
0 评论
0 点赞
2024-03-12
GKD 一款 APP 去广告神器 3000 + 规则订阅
GKD 的功能是 “自动点击”,帮助你点击升级屏幕跳过, 支持 “订阅规则”,满足各种各样的 APP规则订阅Adpro-Team,支持 621 个应用,总共有 1402 条规则组https://raw.gitmirror.com/Adpro-Team/GKD_subscription/main/dist/Adpro_gkd.json5Alsouler,支持 684 个应用,总共有 1562 条规则组https://raw.gitmirror.com/AIsouler/GKD_subscription/main/dist/AIsouler_gkd.json5奥怪https://registry.npmmirror.com/@aoguai/subscription/latest/files教程第一次打开需要在主页开启 “无障碍权限授权”,然后来到【订阅】,点击右下角➕,输入链接,完成订阅,可以点击【应用规则】选择应用详细的广告跳过规则。下载开源地址基于无障碍 + 高级选择器 + 订阅规则的自定义屏幕点击 Android APP | An Android APP with custom screen tapping based on Accessibility, Advanced Selectors, and Subscription Rules https://gkd.li/guide/文章参考【分享】去广告神器!GKD!3000 + 规则分享
2024年03月12日
1,607 阅读
0 评论
1 点赞
2024-03-12
Frps 内网穿透的常见快速部署方式
一个内网穿透服务端,下面整理常见的快速部署方式及其推荐程度一键脚本部署(⭐⭐⭐)Install(安装)Giteewget https://gitee.com/mvscode/frps-onekey/raw/master/install-frps.sh -O ./install-frps.sh chmod 700 ./install-frps.sh ./install-frps.sh installGithubwget https://raw.githubusercontent.com/mvscode/frps-onekey/master/install-frps.sh -O ./install-frps.sh chmod 700 ./install-frps.sh ./install-frps.sh installUninstall(卸载)./install-frps.sh uninstallUpdate(更新)./install-frps.sh updateServer management(服务管理器)Usage: /etc/init.d/frps {start|stop|restart|status|config|version}1Panel 应用商店一键部署(⭐⭐)宝塔应用商店部署(⭐)开源地址Frps 一键安装脚本 & 管理脚本
2024年03月12日
121 阅读
0 评论
0 点赞
2024-03-12
frpc-desktop 一个 frpc 桌面客户端
界面更加美观,使用体验舒适,可自定义客户端版本,强烈推荐小白使用。截图下载64 位计算机 win10/win11,其他的架构可前往文章底部开源地址自行下载。Frpc-Desktop_releaseFrpc-Desktop-Windows-x64-1.0.2-Setup.exe开源地址luckjiawei/frpc-desktopGithub
2024年03月12日
67 阅读
0 评论
0 点赞
2024-03-12
telegraph 和 cloudflare pages 部署免费图床
注意Cloudflare Function 免费版每日限制 100,000 个请求,如果需求大可以选择付费订阅方案由于图片文件实际存储于 Telegraph,Telegraph 限制上传的图片大小最大为 5MB图片加载使用了 cloudflare cdn 网络,在中国大陆访问会有概率受限,可以尝试进行 ip 优选毕竟白嫖,还是够用就好,避免滥用开启图片审查后,因为审查需要时间,首次的图片加载将会变得缓慢,之后的图片加载由于存在缓存,并不会受到影响准备一个正常连接互联网的环境一个 cloudflare 账号一个 GitHub 账号一个域名(也可用 pages 自带的)部署登入 GitHub 并且 fork 该仓库到自己账号备用打开 Cloudflare Dashboard,进入 Pages 管理页面,选择创建项目,选择连接到 Git 提供程序并选择刚刚 fork 的项目,确定根据自身情况修改内容后即可(其实就是起一个你自己喜欢的名字,默认的也行),其他部分不需要操作,然后保存并部署,稍等即可自定义该图床是支持自定义设置的,我们可以进行设置进行绑定域名操作,这一步从 custom domains 即可快速绑定已经解析到 cf 的域名想要开启图片管理功能,依次点击设置->函数->KV 命名空间绑定->编辑绑定->变量名称填写:img_url KV 命名空间 选择你提前创建好的 KV 储存空间,开启后访问 http(s):// 你的域名 / admin 即可打开后台管理页面,我这里的 KV 名称就叫 img_url,因此这样填写,请在使用时将其替换为自己的 KV 名字。开启后访问 http(s):// 你的域名 / admin 即可打开后台管理页面。(不会创建 KV?请看这篇教程)后台可以添加登陆验证,前往后台依次点击设置->环境变量->为生产环境定义变量->编辑变量 添加如下表格所示的变量即可开启登录验证BASIC_USER <后台管理页面登录用户名称> BASIC_PASS <后台管理页面登录用户密码>也可以使用 cloudflare access 进行统一登陆,但是需要注意的是需要保护路径包括 / admin 以及 /api/manage/*关于 cloudflare access 我可能将来也会出一期博客精讲,毕竟真的超级好用开启图片审查,可以前往 https://moderatecontent.com 输入邮箱申请一个图片审查的 api 把申请到的 api 填在刚才提到的环境变量中,添加一个变量名称为ModerateContentApiKey,值为你刚刚第一步获得的 API key还有白名单(不经过审查),黑名单(不予以显示),统计和搜索功能在后台可用最后,在完成这些设置后一定一定要记得重新部署哦!!!只有 web 前端不方便?没关系,我们可以搭配 picgo 进行食用我们需要用到 GitHub - yuki-xin/picgo-plugin-web-uploader 这个插件,可以自行在 C:UsersXXXAppDataRoamingpicgo 输入命令安装,记得重启软件npm install picgo-plugin-web-uploader或者在程序中搜索 web 就可以看到(反正这样我是安装不上)按照如图进行配置然后保存应用即可
2024年03月12日
178 阅读
0 评论
0 点赞
2023-12-29
DailyHot今日热榜部署教程
DailyHot 今日热榜:聚合了多个平台的热搜,一页尽知天下事,推荐部署!项目均来自于imsyy大佬,后端项目:DailyHotApi,前端项目:DailyHot一、准备工作1、一台VPS,安装了基本环境,本教程以宝塔面板为例2、如果打算前后端分离,需要准备两个二级域名,本教程后端域名:hot-api.bbit.fun,前端域名:hot.bbit.fun二、后端API部署1、源码部署clone项目cd /www/wwwroot git clone https://github.com/imsyy/DailyHotApi.git<u>Tips:服务端口以及允许的域名可在根目录下的.evn文件内修改</u>安装Node.js、npm、pnpmapt update -yapt install nodejs npm -ynpm install -g pnpm切换到项目路径、安装依赖cd DailyHotApi pnpm install安装【PM2管理器5.5】我们先到宝塔的软件管理,搜索pm2,安装【PM2管理器5.5】点击PM2管理器 5.5右边的设置,点击Node版本,我选择了v18.19.0,等待切换完成点击【模块管理】,在搜索框输入pnpm,点击【安装】前往 PM2管理器 —项目列表— 添加项目启动文件:选择网站根目录的index.js,比如我的:/www/wwwroot/DailyHotApi/index.js,其他的默认不用管,点击提交最后前往项目列表— 为该项目映射添加域名<u>Tips:如果前端根目录下的.evn文件内是https协议,必须用宝塔申请部署免费SSL证书</u>温馨提醒:如果使用的是如 腾讯云 阿里云 华为云等服务器,需要前往安全组/防火墙 添加设置的服务器端口6688,其它服务器需要在宝塔面板 – 安全 – 添加端口规则至此,API就部署好了测试在浏览器输入:http://你的小鸡ip:6688/,出现以下界面说明成功:2、Docker部署安装及配置 Docker 将不在此处说明,请自行解决本地构建拉取源代码git clone https://github.com/imsyy/DailyHotApi.git构建cd DailyHotApi docker build -t dailyhot-api .运行docker run -p 6688:6688 -d dailyhot-api在线部署// 拉取 docker pull imsyy/dailyhot-api:1.0.5 // 运行 docker run -p 6688:6688 -d imsyy/dailyhot-api:1.0.5后续可以加上cf域名解析+nginx反代三、前端部署前端编译比较耗费内存,请使用至少有2G内存的小鸡或在本地编译1、源码部署clone项目git clone https://github.com/imsyy/DailyHot.git如果是在本地编译,要确保node版本>16.x.x,具体可以看编译时的提示信息修改.env文件将VITE_GLOBAL_API改为你的后端api的url,并修改备案号<u>Tips:如果后端根目录下的.evn文件内是https协议,必须申请部署免费SSL证书</u>编译打包项目cd DailyHot pnpm install pnpm build或者npm打包cd DailyHot npm install npm run build编译完成,没有报错的话,项目目录下会有一个dist目录Nginx部署在宝塔中新建站点,将dist目录下的文件全部复制到宝塔站点根目录中即可2、Docker部署拉取源代码git clone https://github.com/imsyy/DailyHot.git进入目录cd DailyHot编辑start.sh脚本vim start.sh要将API 地址及备案号作为环境变量传入打包好的静态资产并构建镜像需要写一个脚本,内容如下:#!/bin/ash # 替换 API 地址及备案号 find '/app' -name '*.js' -exec sed -i -e 's,http://localhost:6688,'"$API"',g' {} \; find '/app' -name '*.js' -exec sed -i -e 's,豫ICP备2022018134号-1,'"$ICP"',g' {} \; # # 启动 httpd 服务器 httpd -f -p 80 -h /app添加执行权限chmod +x start.sh编辑DockerfileFROM node:16-alpine WORKDIR /app COPY package.json . RUN npm install COPY . . RUN npm run build FROM busybox:1.35.0-uclibc WORKDIR /app COPY --from=0 /app/dist . COPY --from=0 /app/start.sh . ENV API="https://api-hot.imsyy.top" ENV ICP="豫ICP备2022018134号-1" CMD ["/app/start.sh"]构建镜像docker build -t dailyhot-web .运行docker run -d \ --name dailyhot-web \ -p 6677:80 \ -e API="https://hot-api.bbit.fun" \ -e ICP="没有备案捏" \ --restart always \ dailyhot-web修改刚刚搭建的api地址以及备案号,访问ip:6677即可看到热榜后续可以加上cf域名解析+nginx反代参考文档在宝塔面板上部署DailyHotApiDocker部署“dailyhot”部署一个自己的今日热榜(后端+前端)
2023年12月29日
189 阅读
0 评论
1 点赞
2023-12-03
Linux挂载硬盘并自启动
一、查看当前已经分配磁盘的空间情况df -hroot@******# df -h Filesystem Size Used Avail Use% Mounted on udev 126G 0 126G 0% /dev tmpfs 26G 35M 26G 1% /run tmpfs 126G 0 126G 0% /dev/shm /dev/sdb1 454G 31G 401G 8% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 126G 0 126G 0% /sys/fs/cgroup tmpfs 26G 28K 26G 1% /run/user/117 tmpfs 26G 28K 26G 1% /run/user/1000发现新加的硬盘并没有挂载上来, 其中,系统默认磁盘是在/dev/sdb1上二、查看当前磁盘的大小fdisk -lroot@****# fdisk -l Disk /dev/sda: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/sdb: 3.7 TiB, 4000787030016 bytes, 7814037168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xe8caedc1 Device Boot Start End Sectors Size Id Type /dev/sdb1 * 2048 968802303 968800256 462G 83 Linux /dev/sdb2 968804350 976771071 7966722 3.8G 5 Extended /dev/sdb5 968804352 976771071 7966720 3.8G 82 Linux swap / Solaris其中/dev/sda磁盘发现并未使用三、对该磁盘进行分区并格式化fdisk /dev/sda1、通过提示,command,输入m2、根据提示,输入n,新增一个分区这里的 /dev/sda 是步骤(1)中 查询出来的硬盘识别文件地址。如果你在步骤(1)中要格式化的硬盘存在于其他地址请相应改变。在提示信息引导下,我选择(n) “add a new partition” 将硬盘划分为一个新分区。然后选择(e) “extended” 作为扩展分区。因为我整个硬盘只作为一个分区,所以接下来的Partition number,我默认(1)。指定柱面直接默认回车,接下来其他操作也默认回车即可,如果自己有需求自行按照说明选择。最后再输出(p)确认下自己创建的分区表信息是否正确。确认无误后(w)保存。*如果成功,系统会提示“The partition table has been altered” 分区表已更改完毕 。*3、再次查看磁盘分区情况,已经有一个/dev/sda1的磁盘fdisk -l4、对磁盘进行格式化,使用ext4格式,该操作耗时几分钟,耐心等待结束;mkfs -t ext4 /dev/sda1四、挂载新硬盘到文件目录1、新建文件夹我将其保存在本地用户目录下新建文件夹中。创建文件夹命令样例为:mkdir <文件夹路径>2 、挂载硬盘到目录mount /dev/sda1 <文件夹路径>但是发现文件夹权限不足,因此赋予其和其他普通文件夹相同权限:chmod 777 <文件夹路径>权限如有需求相应调整,777是最高权限,然后进入文件夹新硬盘已经可以正常操作使用。五、开机自动挂载1、查看硬盘UUID:blkid这里/dev/vda1的UUID为468f89f6-32b7-432f-bd98-34d6fd8ad375,文件系统类型为ext42、向/etc/fstab写入文件系统的信息echo UUID=468f89f6-32b7-432f-bd98-34d6fd8ad375 <挂载文件夹路径> ext4 defaults 0 0 >> /etc/fstab3、查看新分区信息cat /etc/fstab最后reboot重启,验证开机是否自动挂载
2023年12月03日
67 阅读
0 评论
0 点赞
2023-11-28
搭建一个自己的IP信息工具箱
这是一个完全开源的 IP 信息查看器,可以查询本机 IP、查询任意 IP、查询国内外网站可用性等。这是我第一次用 Vue.js 练手的项目。如果你看着 https://ip.skk.moe 眼馋,那就用这个程序搭建一个属于自己的吧。主要功能看自己的 IP:从多个 IPv4 和 IPv6 来源检测显示本机的 IP看 IP 信息:显示所有 IP 的相关信息,包括国家、地区、ASN、地理位置等可用性检测:检测一些网站的可用性:Google, Github, Youtube, 网易, 百度等WebRTC 检测:查看使用 WebRTC 连接时使用的 IPDNS 泄露检测:查看 DNS 出口信息,以便查看在 VPN/代理的情况下,是否存在 DNS 泄露隐私的风险暗黑模式:根据系统设置自动切换暗黑/白天模式,也可以手动切换简约模式:为移动版提供的专门模式,缩短页面长度,快速查看最重要的信息查任意 IP 信息:可以通过小工具查询任意 IP 的信息根据可用性检测结果,返回目前是否可以访问全世界网络的提示搭建教程建立站点 我这里用的是宝塔面板,其他面板或者裸 nginx 自行添加即可。填写你的域名,并且做好解析和 SSL 证书。注意这里 PHP 版本选择纯静态即可,因为此项目是一个 Vue.JS 纯前端项目,不涉及 PHP。2.上传源代码源代码下载地址: https://github.com/jason5ng32/MyIP远程 URL 直链: https://github.com/jason5ng32/MyIP/archive/refs/heads/main.zip进入到网站根目录,删除掉宝塔自动创建的文件后下载代码包。我的服务器是有宝塔面板,所以我这里直接使用 远程下载 功能。3.解压代码,安装步骤即完成。非常简单,开箱即用。4.访问你的解析域名地址 查看预览效果。优化调整对接 Bing Map也可以选择使用对接 Google Map 是永久免费的,但是 Google Maps 因为长城的缘故也无法国内使用。所以我选择去申请一个 Bing Maps 的 API,也是免费的,但是一年只能发起 12 万次请求,个人公益使用完全够用。如果想做更大的请求的话,去使用 Google Map 或者国内的 API 吧~a.进入到 Bing Maps 官网,使用 Microsoft 登录,但是注意 Bing 是单独的部门,还是要注册的。b.注册登录之后来到 My Keys 选项卡。 c.填写信息创建一个 key。d.复制 Key 并且添加到 app.js 中。e.现在我们就可以在主界面中看到地图了。2、IP数据显示错误这应该是一个小 Bug,原作者的编写平台可能是 MacOS,这是一个 emoji 表情,但是在 Windows 平台上会显示一个小方块。解决办法也很简单,在 index.html 中搜索 IP 数据。将
2023年11月28日
313 阅读
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日
100 阅读
0 评论
1 点赞
1
2
...
9