简介 本贴用于转载阅读书源，持续更新，大部分书源转载至酷安酷友。 导入地址 序号 转载至 书源名 转载时间 网络导入链接 1 酷安——无畏的勇者 12,000多书源中挑选出来的可用书源.json 2022-08-02 http://www.ersansi.top/usr/uploads/2022/08/3815470571.json 2 酷安——狗吧哎呀 shareBookSource 2022-08-02 http://www.ersansi.top/usr/uploads/2022/08/2959536361.json 3 酷安——大于五个字的名字 2211.json 2022-08-10 http://www.ersansi.top/usr/uploads/2022/08/3195996207.json 4 酷安——水击三千里 阅读小说源.json 2022-08-16 http://www.ersansi.top/usr/uploads/2022/08/3137867632.json 5 酷安——江潶一 1235个阅读书源.json 2022-8-22 http://www.ersansi.top/usr/uploads/2022/08/3769068048.json 6 酷安——onede 自用精简96个书源 2022-8-22 http://www.ersansi.top/usr/uploads/2022/08/780421083.json 7 酷安——GIO10 2022.09.04-122个书源3.0 2022-09-06 http://www.ersansi.top/usr/uploads/2022/09/1376368832.json 8 酷安——天外神人 10月4日更新耽美源 2022-10-06 http://www.ersansi.top/usr/uploads/2022/10/3595336488.json 9 酷安——你就像人间的四月天 278精简书源bookSource 2022-11-08 http://www.ersansi.top/usr/uploads/2022/11/2690764375.json 10 酷安——GIO10 2022.11.12-98个书源3.0 2022.11.15 http://www.ersansi.top/usr/uploads/2022/11/3892847119.json 11 酷安——烟火弥尘埃 阅读书源424（22.11.12） 2022.11.15 http://www.ersansi.top/usr/uploads/2022/11/2768876674.json 12 酷安-dfvh5585 shareBookSource 2022.12.14 http://www.ersansi.top/usr/uploads/2022/12/3998569908.json 13 酷安-你好223 十三个自用最新书源 2022.12.18 http://www.ersansi.top/usr/uploads/2022/12/1306446676.json 14 酷安——Aaa12321 bookSource 2023.02.18 http://www.ersansi.top/usr/uploads/2023/02/313207948.json 15 酷安——喵喵要吃鱼 1200+书源 2023.02.18 http://www.ersansi.top/usr/uploads/2023/02/3764130148.json 16 酷安——GIO10 23.02.07-87个书源3.0 2023.02.18 http://www.ersansi.top/usr/uploads/2023/02/3931045881.json 17 酷安——你就像人间四月天 5月 2023.04.28 http://www.ersansi.top/usr/uploads/2023/04/1783659886.json 18 酷安——你就像人间四月天 补5月 2023.04.28 http://www.ersansi.top/usr/uploads/2023/04/3676747302.json 19 酷安——念丶无 4.23经过校验的1789个书源 2023.04.28 http://www.ersansi.top/usr/uploads/2023/04/2956601975.json 20 酷安——北极星KKO 最新880可用源 2023-05-24 http://www.ersansi.top/usr/uploads/2023/05/2175564240.json 21 酷安——念丶无 5.24 2804书源 2023-05-24 http://www.ersansi.top/usr/uploads/2023/05/2296881681.json 22 酷安——分享好软 bookSource 2024-03-12 https://www.ersansi.top/usr/uploads/2024/03/1471212115.json 23 酷安——流年醉 1037书源 2024-03-12 https://www.ersansi.top/usr/uploads/2024/03/2203739066.json 24 酷安——时空之主 时空之主分享 2024——03——12 https://www.ersansi.top/usr/uploads/2024/03/2459512395.json 25 酷安——不可須臾离也 不可須臾离也书源 2024-03-12 https://www.ersansi.top/usr/uploads/2024/03/1103022087.json 26 酷安——行走的鱼 5.27 2024-05-28 https://www.ersansi.top/usr/uploads/2024/05/3959326386.json
简介 我之前有一个页面是专门分享一些我感觉比较实用的网站的，那个页面是使用友链页面做的，然后我在更换主题的时候忘记备份主题的配置，导致了分享的数据丢失，所以现在打算改成使用文章记录了 投稿 如果同学们有好的网站也可以在下方留言，我看了之后感觉可以的我会收录进去的哦~ 图片/图标类 序号 网站名称 网站简介 链接 1 wallhaven 一个免费下载图片的网站，无需登录和注册 点击跳转 2 Undraw 一个免费的无版权插画库 点击跳转 3 icones 一个免费的小图标分享网站 点击跳转 4 PIXIV 动漫图片P站，里面有各种二次元插图 点击跳转 软件/系统资源分享 序号 网站名称 网站简介 链接 1 软件SOS 一个免费下载各种破解软件的网站，需要微信扫码登录 点击跳转 2 果核剥壳 免费分享各种绿色软件 点击跳转 3 Github 一个开源分享平台，在这上面找到很多好用的开源资源 点击跳转 4 SMDN 一个下载微软原版系统及软件的网站，例如下载windows系统等 点击跳转 5 Github项目 VM虚拟机官方原版下载 点击跳转 6 voidtools 免费电脑文件搜索小工具，搜索速度比电脑自带更快，搜索秒出 点击跳转 7 Ventoy 制作可启动U盘的开源工具，做好启动盘之后把系统复制到U盘里面即可安装 点击跳转 8 V2rayu MAC OS科学小工具，有X86的和ARM的 点击跳转 9 IDM分享 夸克网盘分享最新版的IDM 点击跳转 工具类 序号 网站名称 网站简介 链接 1 图标抓取 免费抓取某个网站的logo 点击跳转 2 IP地址查询 在线免费查询IP地址 点击跳转 3 极简简历 一个免费在线制作简历的网站 点击跳转 4 闪链-在线文件解析 百度网盘下载解析，免费，每天可以解析10次，每次最大10G， 点击跳转 5 Multi-service image search 以搜图网站，只能搜索动漫类 点击跳转 6 SauceNAO Image Search 以图搜索网站，只能搜索动漫类 点击跳转 7 AI正则表达式生成器 生成各种语言的正则表达式 点击跳转 8 aconvert 免费无需注册文件格式在线转换，支持视频、图片、音频等 点击跳转 9 chartcube 免费生成图表，导入数据即可，例如生成柱状图之类的 点击跳转 10 KMSCX 在线生成windows激活脚本 点击跳转 11 MAS windows，office等激活脚本 点击跳转 12 Charles 激活码计算器 在线生成Charles激活码 点击跳转 13 IPV6测试 测试自己的电脑是否接入了IPV6 点击跳转 14 Type Words 开源单词与文章练习工具 点击跳转 15 无损音乐下载 下载各种无损音乐，包括歌词 点击跳转 文件资源类 序号 网站名称 网站简介 链接 1 woodo 免费下载PPT模板 点击跳转 2 书栈网 一个免费在线阅读和下载电子书的网站，提供了各种开发文档和使用手册 点击跳转 3 优品PPT 免费下载PPT模板 点击跳转 4 z-library 免费图书下载，各个出版社的大部分都有 点击跳转 论坛类 序号 网站名称 网站简介 链接 1 恩山无线论坛 一个路由器固件论坛 点击跳转 2 远景论坛 一个电脑折腾论坛 点击跳转 3 JIKE 一个分享论坛，里面有各种技术、电视资源分享 点击跳转 4 爱好论坛 一个分享windows激活码的论坛 点击跳转 其他类 序号 网站名称 网站简介 链接 1 搬瓦工机房公告 查看搬瓦工机房维护进度 点击跳转
简介 vaultwarden的前端是可以设置中文的，但是后台和邮件模板是不能直接设置的 官方给了我们自己翻译的方法 既然官方给了教程，那么网上肯定有大佬翻译好了，我们直接拿过来使用就可以了 今天使用到的这个项目大佬还打包了中文的docker镜像，如果感觉自己配置中文麻烦，那么直接切换大佬打包的镜像就可以了 中文项目地址 这里有大佬已经把整个项目翻译成中文了 地址：https://github.com/vlianx/vaultwarden_zh_cn 下载模板 我这里不切换镜像了，直接把大佬的模板配置进去 首先我们打开大佬的项目 然后点击右上角的“Code”，选择“Download ZIP” 然后把下载好的zip压缩包解压出来 上传文件 首先查看我们的docker-compose文件，确定数据持久化的目录 进入我们数据持久化目录 创建一个名称为templates的目录 mkdir templates 然后把我们解压的文件夹里面的vaultwarden_zh_cn-main\src\static\templates目录下的“admin”,“email”,“scss”文件夹上传到我们刚刚在服务器上创建的“templates”文件夹里面 修改变量 打开我们的docker-compose文件，新增一个变量，变量名称为TEMPLATES_FOLDER:，变量的值是docker被映射的数据目录下的templates目录 例如我映射的是 volumes: - /opt/vaultwarden/data/:/data/ 那么新增的这个变量的值就是 /data/templates 完成 修改完成后，重启docker容器，再次进入后台就可以看到是中文的了 但是这个后台管理模板官方给的能翻译的地方不多，聊胜于无吧 发送一个测试邮件，可以看到邮件也是中文的了
简介 vaultwarden是一个开源的密码管理工具，目前这个项目收藏有50.9K，是一个很出名的密码管理工具了 这时候有同学可能会有个疑问，那就是我们的浏览器以及自带密码管理了，还有比较部署这个吗？ 接下来说一下我对这个工具的理解 首先这个是自托管的，也就是意味着数据掌握在自己手里 其次就是实用性，我感觉这个比浏览器自带的密码管理好用多了，浏览器自带的密码管理只能管理你在这个浏览器上使用的密码，一旦你换浏览器了就得导出密码从新导入，使用这个工具就不会有这样的问题，换浏览器后直接安装一个插件即可 然后就是跨端跨设备，使用这个工具你不但可以在电脑上使用，这个工具有移动端，你也可以在移动端上使用，这样你的密码更集中管理，更方便管理 还有一点就是团队使用，这个工具可以建立组织，让同一个组织的人员都可以共同调用密码，这个对于那种一个账号多共享的还是很实用的 项目地址 https://github.com/dani-garcia/vaultwarden 开始部署 这里的部署不止可以使用docker，还可以是二进制文件，但是使用二进制文件需要自己编译，所以我选择使用docker部署，很方便 这里就不重复docker和docker-compose的安装了，如果不会安装的可以参考这篇文章《从零开始学习Docker--Docker的安装和配置仓库源加速》 编写docker-compose文件 首先我们编写docker-compose文件，我们打开项目地址 滑倒下面，这里官方以及给了一个基础的docker-compose文件了，我们只需要在这个基础上修改即可 复制这个文件下来，新建一个记事本，粘贴进去 接下来我们需要修改的地方就三个，一个是变量，一个是数据持久化，还有就是端口 变量 必须变量 首先是变量，这里基础的docker-compose文件里面有一个DOMAIN: "https://vw.domain.tld"变量，这个变量是配置站点根目录 也就是说你的站点的域名的，如果没有域名，使用的ip就直接填写ip即可，但是这里注意的是，如果不是局域网使用建议配置域名和证书，否则你的数据就会以明文传输，意味着你的密码将会在网络上暴露 我这里时在局域网内演示，所以我直接填写ip地址 演示配置其他变量，非必须 这里我在演示一下配置其他变量，这个不是必须的，可以不用配置，都是可以在系统后台管理里面配置的 然后我们在项目地址网上翻，找到官方的变量说明，找到自己需要的变量添加上去 例如我还需要配置邮件服务，用于身份验证和发送忘记密码的时候密码提示 在项目首页找到“Usage”，在里面找到“Wiki”，点击查看详细的说明 我们在右边的导航栏里面找到“Configuration”，里面有一个“SMTP configuration”，点击查看 这里就可以看到官方给的启动示例文件了，-e开头的都是启动变量，我们可以把这个变量直接写入我们的docker-compose文件里面 我们把-e开头的全部复制，粘贴到记事本里面，粘贴的位置在刚刚我们改的ip的那个变量下面 docker-compose文件如果需要注释的话可以时#号开头 然后把前面的-e和后面的\删掉，记得保持缩进和ip那个变量一样 配置管理员 如果你不想直接在docker-compose文件里面配置邮箱等其它配置，那么就需要配置管理员，通过管理员进入系统后台进行配置 我们在右边目录里面找到“Enabling admin page”，点击打开 也是-e开头的，复制到记事本里面 然后把=号后面改成一个你的密码 注意 到这里我们的变量并没有配置完成，有细心的同学可能发现了，官方默认改的DOMAIN: "http://192.168.99.25"这个变量不是=号 是的，这里我们还需要把变量里面的=号换成:（冒号+一个空格），记住，冒号一定要英文的 数据持久化 接下来就是数据持久化了 在官方的配置文件里面其实已经做了数据持久化，但是我还是习惯改成绝对路径 volumes:下面的就是数据持久化 官方的是 - ./vw-data/:/data/ 这里就看自己心情修改了，但是注意的是你只能修改:前面的，后面的不要修改 下面这个是我修改的路径 /opt/vaultwarden/data 端口/地址映射 官方给的配置文件的端口映射是把宿主机的8000端口映射到容器的80端口，这里可改可不改，如果你的服务器的8000端口没有被占用就没必要修改 这里要修改也是只能修改80端口前面的:前面的内容，后面的是不能修改的 下面是我修改后的内容，我把原本的8000端口改成了8080端口 还有就是8080端口前面的地址127.0.0.1，这个就限制了我们只能本机访问，也就是只能服务器自己访问，如果我们做反向代理的话这个不用修改，保持127.0.0.1即可，如果不做反向代理，那么就改成0.0.0.0，允许所有地址访问 创建目录 之前的docker-compose文件我们做了一个绝对路径的数据持久化，我们需要把目录创建好 ssh连接上服务器，执行下面命令，记住，创建的目录一定是你要做数据持久化的目录 mkdir -p /opt/vaultwarden/data 然后我们进入/opt/vaultwarden cd /opt/vaultwarden 在创建一个用于存放docker-compose文件的目录，当然也可以不创建，直接把docker-compose文件扔你记得的地方，看个人习惯来 mkdir config 进入我们创建的config目录 cd config 创建docker-compose.yaml文件 刚刚我们以及在记事本上编辑好docker-compose文件了，现在就需要我们在config目录下使用vi创建一个docker-compose.yaml文件，然后把记事本上的内容粘贴进去 vi docker-compose.yaml 然后按【i】进入编辑模式，把刚刚记事本上的内容粘贴进来 按【esc】编辑模式，输入“:wq”保存并退出 执行部署 在config目录下也就是我们存放docker-compose文件的目录下执行下面命令开始拉取镜像并部署 docker compose up -d 完成部署 看到下面内容就是部署完成了 可以使用下面命令查看是否成功运行，只要看到端口正常就成功运行了 docker ps 用户登录 在浏览器上输入服务器地址加上刚刚我们docker-compose文件里面写的端口号访问，我的是8080端口 这时候你会发现一直在转圈圈 那是因为我们没有配置证书，即使我们在docker-compose里面的DOMAIN: "
简介 上一篇文章说了怎么在netlib.re上注册域名并且托管到CF，但是netlib.re时需要六个月内登录一次的次啊能保活 这篇文章教大家如果使用Github上开源的项目进行自动保活，全程无需人工干预 保活项目地址 Github：https://github.com/eooce/Auto-login-netlib netlib.re保活 进入Github项目地址 然后点击顶部的“Fork”把项目克隆到我们的Github仓库 点击“Create fork” 点击顶部的“Actions” 点击“I understand my workflows, go ahead and enable them” 返回仓库主页 点击顶部的“Settings” 点击左边导航栏的“Secrets and variables” 点击“Actions”，添加变量 点击绿色的“New repository secret” 然后再Name栏填入变量名 ACCOUNTS 下面填入账号和密码，账号密码之间用英文冒号分隔，账号与账号之间英文逗号分隔，例如下面 单账号：账号1:密码1 多账号：账号1:密码1,账号2,密码2 例如我时多账号，我第一个账号名为xxhh，密码为xxhh789987，第二个账号为xxyy，密码为xxyy567890，那么我就应该像下面这样填入 xxhh:xxhh789987,xxyy:xxyy567890 填写完成后点击“Add secret” 下面这样就是添加好了 接下来返回仓库主页 点击顶部的“Actions” 点击“Netlib Keepalive” 点击“Enable workflow”检查配置是否有误 点击“Run workflow” 点击绿色的“Run workflow” 等待一小会，等它弹出下面这个界面 可以点击正在运行的工作流，进去查看 我这里已经运行完成了，我们点击进入 然后点击“Run lognin script”查看结果 这里自动保活就完成了 这个是每30天自动登录一次，也可以自己修改，如果需要自己修改登录天数可以，如果需要修改可以进入.github/workflows目录下修改login.yml文件
简介 现在想要永久免费获取一个域名还是很简单的，但是托管到cf时会有各种问题，如果掌握了正确的姿势，那么也是很简单的，很多永久免费的域名都是托管不到CF的 注意事项 今天我们使用来申请域名的网站是https://www.netlib.re/，但是这个网站有BUG，有个坑，如果你不注意那么你申请到的域名就无法托管到CF，或者侥幸托管上去了但是边缘证书验证不通过，这样的托管也是没用的，即使你删除已经申请的域名从新申请也是不行的，也就是说一旦失败，那么你这个域名将会和CF无缘了，所以一定要紧跟教程一步一步做 这个BUG就是我们申请域名后必须马上把默认的NS修改成CF的，否则等后面是修改不成功的，只要默认NS提交上去了我们就修改不了，这就会导致托管到CF失败。 这个BUG可能作者后续会修复，这个也是不清楚的 第一步：注册netlib.re 打开上面给的网址 点击右上角的“Register” 填写注册信息，这里的邮箱最好使用自己的邮箱，不要使用临时邮箱，以防万一后面作者发送邮件进行验证之类的 信息填写完成后滑倒最下面，勾选I have read and accept the terms of service and privacy policy.，然后点击“Validate” 成功后会转到邮箱验证界面 打开邮箱，复制token 返回验证界面，填写用户名和token，然后点击“Validate” 完成后跳转到登录界面，这时候就可以使用刚刚注册的时候填写的用户名和密码登录了 填写用户名和密码，点击“Validate”登录 第二步：申请一个不需要的域名 我们做这个步骤的原因是我们要获取自己CF的NS，每个账号的SN和不同时间解析的NS都是不一样的，所以我们需要先申请一个自己不需要的域名按照正常流程托管到CF获取自己的NS 登录成功后，可以看到有两个域名可以选择，我们选择第一个“.netlib.re”，这个是可以托管到CF的，而另一个不行 然后随便输入一个三级域前缀，然后点击“add a new domain” 成功后就可以看到我们申请的域名了 第三步：获取CF的NS 打开登录CF，我们按照正常流程托管域名，点击左上角的“加入域” 填写刚刚申请到的域名，然后点击“继续” 选择免费的计划 复制这两个NS保存备用，到这里我们就获取到CF的NS了 第四步：正式申请域名以及修改NS 现在就可以正式申请和托管域名了 输入我们想要的三级域名前缀，然后点击“add a new domain” 之后马上点击我们刚刚添加的域名 跳转到域名设置界面后马上下滑，找到“Delegation”下的“Delegate your domain to different name servers”并点击 然后把刚刚我们获取到的NS填入进去，填入完成后点击“Delegate the domain”保存 看到下面这个界面的时候就是成功了 第五步：托管域名 打开CF，按照正常流程添加域名 点击“加入域” 输入我们刚刚正式申请的域名，然后点击“继续” 选择免费计划 到下面这个界面，只要C没有提示删除其他名称服务器就成功了，耐心等待几分钟 第六步：确定托管是否可用 返回到主页，点击我们刚刚托管的域名 点击左边导航栏的“SSL/TLS” 点击“边缘证书” 看到边缘证书状态为“有效”就是成功了 声明 次方法不确定什么时候失效，目前还是可以正常托管的，不知道后面会不会像cloudns一样托管不上去了
简介 Ventoy是一个制作可启动U盘的开源工具。 有了Ventoy你就无需反复地格式化U盘，你只需要把 ISO/WIM/IMG/VHD(x)/EFI 等类型的文件直接拷贝到U盘里面就可以启动了，无需其他操作。 你可以一次性拷贝很多个不同类型的镜像文件，Ventoy 会在启动时显示一个菜单来供你进行选择 你还可以在 Ventoy 的界面中直接浏览并启动本地硬盘中的 ISO/WIM/IMG/VHD(x)/EFI 等类型的文件。 Ventoy 安装之后，同一个U盘可以同时支持 x86 Legacy BIOS、IA32 UEFI、x86_64 UEFI、ARM64 UEFI 和 MIPS64EL UEFI 模式，同时还不影响U盘的日常使用。 Ventoy 支持大部分常见类型的操作系统 （Windows/WinPE/Linux/ChromeOS/Unix/VMware/Xen ...） （上面简介复制Ventoy官方的） 既然都出这个教程了，那就从零开始吧，从如何制作启动盘开始吧 准备工具 一个U盘 一台电脑 下载Ventoy 打开Ventoy官网 https://www.ventoy.net/cn/index.html 点击顶部导航栏的【下载】 选择对应自己系统的版本，我选择的windows 点击后会跳转到github上 继续点击对应的系统版本下载 等待下载完成后解压 制作启动盘 把U盘插入电脑，记得备份你的资料，U盘要格式化的 然后打开刚刚解压的文件夹 双击运行“Ventoy2Disk.exe” 选择好U盘，然后点击【安装】 弹出是否格式化，点击【是】 完成后点击【确定】 修改主题 下载主题 我们并不需要自己去做主题，我们直接拿别人做好的来使用即可，当然如果想自己做也是可以的，但是这篇文章不会教如何自己做，后续可能会单独开一篇文章来说 首先我们去寻找自己喜欢的主题，寻找的渠道有两个，一个是github，另外一个是下面这个网站 https://www.gnome-look.org/browse/ 打开后我们点击右边的“GRUB Themes” 点击顶部的“Rating”，按评分排序 找到自己喜欢的，点击进去 点击右上角的【Download】下载 点击【Download】后如果有多个文件会弹出一个列表，让你选择下载哪一个，如果不清楚可以进入下面的github地址看一下说明 例如这个，进入github后就可以看到那个名字的主题是什么样的 等待几秒，然后点击【Download】 下载完成后解压出来 设置主题 进入我们第一个下载解压出来的Ventoy文件夹 双击运行“VentoyPlugson.exe”，选择好U盘，然后点击【启动】 这时候会打开浏览器，进入设置界面 导入主题 点击左边的“主题插件” 找到“file —— 主题配置文件”，点击右边的【新增】 这时候会叫我们输入文件路径 我们打开刚刚解压的主题文件夹 打开里面的“darkmatter”文件夹 找到“theme.txt”这个文件 复制文件路径，并填写到浏览器中刚刚我们点击【新增】弹出来的窗口中，然后点击【确定】 这里有一个坑，那就是解压出来的主题压缩包一定要放到Ventoy的U盘里面，否则会路径不对 提示配置文件保存成功，文件存在就可以了 到这里就结束了，可以关闭所有窗口了，可以重启看看是否成功了
简介 之前使用的云服务器都是阿里云的，主要是阿里云便宜，但是最近不知道什么问题，使用阿里云的服务器延迟总是很高，然后丢包率也高，所以换了腾讯云 虽然说腾讯云比阿里云贵了那么亿点，但是真TM稳啊，应该是线路优化了 每家的云服务器都会有监控进程，这些进程不能说没有用，还是有那么一点用处的，但是占用资源高啊 如果在系统进程中看到YDService、tat_agent、YDLive、sgagent、barad_agent这些都是云镜、云监控相关软件的进程 卸载云镜等命令 systemctl stop tat_agent systemctl disable tat_agent /usr/local/qcloud/YunJing/uninst.sh /usr/local/qcloud/stargate/admin/uninstall.sh /usr/local/qcloud/monitor/barad/admin/uninstall.sh 删除云监控相关目录文件 rm -f /etc/systemd/system/tat_agent.service rm -rf /usr/local/qcloud 最后清理 打开/etc/rc.local 文件，将里面含qcloud的行全部删掉。 vi /etc/rc.local 找到包含qcloud的，全部删掉 然后重启服务器
简介 Vikunja是一款功能强大的开源任务管理工具，它帮助用户以一种有组织的方式管理和跟踪所有待办事项。 就像一个拥有超能力的笔记本，Vikunja允许个人或团队轻松地规划、协作并完成项目。 无论是个人使用还是团队合作，Vikunja都提供了灵活性和定制性，让用户能够根据自己的需求调整任务管理方式 环境与安装方式 Vikunja支持二进制安装，docker安装，从源码自己构建安装，我这里使用的是二进制安装 我安装的环境是X86架构的linux（Almalinux） 项目官网/下载地址 和其他的开源程序不一样，这个再Github里面也可以找到，但是里面只有源码，没有编译好的二进制文件等，需要二进制文件的话可以到它的官网下载。 项目官网：https://vikunja.io/ github项目地址：https://github.com/go-vikunja/vikunja 官方下载仓库地址：https://dl.vikunja.io/vikunja/ 下载/解压Vikunja 进入官方的下载仓库地址 点击最新版的版本号，这里注意，有的版本号带rc的，带rc的是候选版本，可以理解为测试版本，我们需要的是稳定版的 找到适合自己服务器软硬件的版本，鼠标右键，复制链接地址 使用ssh工具连接到服务器，然后根据自己的习惯创建一个文件夹，用于存放软件，我的习惯是自己安装的软件放在/opt/下面对应的文件夹里面 cd /opt mkdir vikunja 进入刚刚创建的文件夹 cd vikunja 使用wget命令下载刚刚复制的链接 wget 刚刚再下载仓库复制的链接 wget https://dl.vikunja.io/vikunja/0.24.6/vikunja-v0.24.6-linux-amd64-full.zip 下载完成后可以使用ls命令查看下载的文件 下载下来的是一个zip包，使用unzip解压，解压完成后可以使用ls命令查看解压出来的文件 unzip vikunja-v0.24.6-linux-amd64-full.zip 为了方便管理，我们需要删除不需要的文件 rm LICENSE vikunja-v0.24.6-linux-amd64-full.zip vikunja-v0.24.6-linux-amd64.sha256 然后把二进制文件重命名一下，方便后续升级更新 mv vikunja-v0.24.6-linux-amd64 vikunja 配置Vikunja 刚刚解压出来的文件里面有一个config.yml.sample，这个是官方的配置示例文件，我们可以在这个文件上进行修改或者参考这个文件写一个新的config.yml文件 下面是翻译后的配置文件示例 service: # 此令牌用于验证签发的 JWT 令牌。 # 默认是随机生成的，每次启动 Vikunja 都会生成新的。 # （这意味着重启 Vikunja 后所有已签发的令牌都会失效） JWTSecret: "<jwt-secret>" # JWT 令牌有效期（秒），默认 259200 秒（3 天） jwtttl: 259200 # “记住我”模式令牌有效期（秒），默认 2592000 秒（30 天） jwtttllong: 2592000 # Web 服务器运行接口 interface: ":3456" # Unix 套接字路径，如果设置，将使用套接字而不是 TCP unixsocket: # Unix 套接字权限，八进制值需以 0o 前缀，例如 0o660 unixsocketmode: # 用户访问 Vikunja 的公共 URL，用于邮件和前后端通信 publicurl: "" # 可执行文件和资源所在的根路径 # Vikunja 也会在此路径查找配置文件 rootpath: <rootpath> # 每页最大返回项目数 maxitemsperpage: 50 # 是否启用 CalDAV 接口 enablecaldav: true # 设置每日消息（MOTD），通过 /info 接口可见 motd: "" # 是否允许通过链接共享项目 enablelinksharing: true # 是否允许新用户自行注册 enableregistration: true # 是否允许任务附件 enabletaskattachments: true # 所有时间戳使用的时区，需使用官方 tz 数据库名称（UTC/GMT 不可用） timezone: GMT # 是否启用任务评论 enabletaskcomments: true # 是否启用 TOTP 双因素认证 enabletotp: true # 如果不为空，将启用 /test/{table} 接口用于测试，可写入任意内容 # 非常危险，除非明确知道用途，否则不要启用 testingtoken: '' # 是否在任务到期时发送邮件提醒 enableemailreminders: true # 是否允许用户请求删除账号 enableuserdeletion: true # 用户头像最大尺寸（KB） maxavatarsize: 1024 # 是否显示演示模式警告（数据会被清空） demomode: false # 是否允许根据节日更换图标 allowiconchanges: true # 是否允许使用自定义 Logo customlogourl: '' # 是否启用公开团队功能，使团队可被发现 enablepublicteams: false sentry: # 是否启用 API 错误匿名跟踪（Sentry） enabled: false # 配置 Sentry DSN 用于 API 错误跟踪 dsn: "https://440eedc957d545a795c17bbaf477497c@o1047380.ingest.sentry.io/4504254983634944" # 是否启用前端错误匿名跟踪 frontendenabled: false # 配置 Sentry DSN 用于前端错误跟踪 frontenddsn: "https://85694a2d757547cbbc90cd4b55c5a18d@o1047380.ingest.sentry.io/6024480" database: # 数据库类型，可选 sqlite、mysql、postgres type: "sqlite" # 数据库用户名 user: "vikunja" # 数据库密码 password: "" # 数据库主机 host: "localhost" # 数据库名称 database: "vikunja" # 使用 sqlite 时数据库文件路径 path: "./vikunja.db" # 数据库最大打开连接数（仅 mysql/postgres） maxopenconnections: 100 # 数据库最大空闲连接数（仅 mysql/postgres） maxidleconnections: 50 # 单个数据库连接最大存活时间（毫秒） maxconnectionlifetime: 10000 # postgres 安全连接模式，可选 disable/require 等 sslmode: disable # postgres 客户端证书路径 sslcert: "" # postgres 客户端密钥路径 sslkey: "" # postgres 根证书路径 sslrootcert: "" # mysql 启用 SSL/TLS，可选 false/true/skip-verify/preferred tls: false typesense: # 是否启用 Typesense 集成，启用后所有任务通过 Typesense 搜索 enabled: false # Typesense 实例 URL url: '' # Typesense API key apikey: '' redis: # 是否启用 Redis enabled: false # Redis 服务器地址和端口 host: 'localhost:6379' # Redis 密码 password: '' # 使用的数据库编号（0 为默认） db: 0 cors: # 是否启用 CORS 头 enable: false # 允许访问 API 的来源列表（需包含协议 http:// 或 https://） origins: - "*" # 预检请求结果缓存时间（秒） maxage: 0 mailer: # 是否启用邮件功能，禁用后用户注册立即生效且无法重置密码 enabled: false # SMTP 主机 host: "" # SMTP 端口（若遇 EOF 错误可尝试改为 25） port: 587 # SMTP 验证类型，可选 plain、login、cram-md5 authtype: "plain" # SMTP 用户名 username: "user" # SMTP 密码 password: "" # 是否跳过 TLS 验证 skiptlsverify: false # 默认发件人邮箱 fromemail: "mail@vikunja" # 邮件队列长度 queuelength: 100 # 邮件连接超时时间（秒） queuetimeout: 30 # 是否强制使用 SSL forcessl: false log: # 日志文件保存目录 path: <rootpath>logs # 是否启用日志 enabled: true # 普通日志输出方式，可选 stdout/stderr/file/off standard: "stdout" # 日志级别，可选 CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG level: "INFO" # 是否记录数据库查询（调试用），可选 stdout/stderr/file/off database: "off" databaselevel: "WARNING" # 是否记录 HTTP 请求 http: "stdout" # Echo 日志，通常不需要 echo: "off" # 是否记录事件日志 events: "off" eventslevel: "info" # 是否记录邮件相关日志 mail: "off" maillevel: "info" ratelimit: # 是否启用速率限制 enabled: false # 速率限制类型，可选 user 或 ip kind: user # 限制周期（秒） period: 60 # 单位周期最大请求数 limit: 100 # 计数存储方式，可选 keyvalue/memory/redis store: keyvalue # 未认证用户每分钟访问限制（登录、注册、密码重置等接口） noauthlimit: 10 files: # 文件存储路径 basepath: ./files # 相对于二进制文件 # 文件最大体积 maxsize: 20MB migration: todoist: # 是否启用 Todoist 导入 enable: false # Todoist API client id clientid: # Todoist API client secret clientsecret: # 授权后回调 URL redirecturl: <service.publicurl>/migrate/todoist trello: # 是否启用 Trello 导入 enable: false key: redirecturl: <frontend url>/migrate/trello microsofttodo: # 是否启用 Microsoft ToDo 导入 enable: false clientid: clientsecret: redirecturl: <frontend url>/migrate/microsoft-todo avatar: # 使用 Gravatar 时缓存过期时间（秒） gravatarexpiration: 3600 backgrounds: # 是否启用项目背景 enabled: true providers: upload: # 是否允许上传背景 enabled: true unsplash: # 是否允许 Unsplash 背景 enabled: false accesstoken: applicationid: legal: # 法律相关 URL，会显示在前端 imprinturl: privacyurl: keyvalue: # 键值存储类型，可选 memory 或 redis type: "memory" auth: # 本地认证设置 local: enabled: true # OpenID 第三方认证 openid: enabled: false providers: - name: authurl: logouturl: clientid: clientsecret: scope: openid email profile metrics: # 是否启用 Prometheus /metrics 端点 enabled: false username: password: defaultsettings: # 新用户默认设置 avatar_provider: initials avatar_file_id: 0 email_reminders_enabled: false discoverable_by_name: false discoverable_by_email: false overdue_tasks_reminders_enabled: true overdue_tasks_reminders_time: 9:00 default_project_id: 0 week_start: 0 language: <unset> timezone: webhooks: # 是否启用 Webhooks enabled: true timeoutseconds: 30 proxyurl: proxypassword: 配置文件修改位置 我的配置文件主要修改了以下几个地方： 1、service模块 JWTSecret 设置为固定的 publicurl 设置为域名 rootpath 改为二进制文件的绝对路径 timezone 改为 GMT 2、mailer模块 SMTP 邮箱配置改为你的 QQ 邮箱 password 改为邮箱授权码 3、log模块 日志路径改为 /opt/vikunja/log/ 4、defaultsettings模块 language 改为 zh-CN timezone 改为 Asia/Shanghai 下面是我修改后的配置文件 service: # 此令牌用于验证签发的 JWT 令牌。 # 默认是随机生成的，每次启动 Vikunja 都会生成新的。 # （这意味着重启 Vikunja 后所有已签发的令牌都会失效） JWTSecret: "12345678" # JWT 令牌有效期（秒），默认 259200 秒（3 天） jwtttl: 259200 # “记住我”模式令牌有效期（秒），默认 2592000 秒（30 天） jwtttllong: 2592000 # Web 服务器运行接口 interface: ":3456" # Unix 套接字路径，如果设置，将使用套接字而不是 TCP unixsocket: # Unix 套接字权限，八进制值需以 0o 前缀，例如 0o660 unixsocketmode: # 用户访问 Vikunja 的公共 URL，用于邮件和前后端通信 publicurl: "https://task.ersansi.top" # 可执行文件和资源所在的根路径 # Vikunja 也会在此路径查找配置文件 rootpath: /opt/vikunja/ # 每页最大返回项目数 maxitemsperpage: 50 # 是否启用 CalDAV 接口 enablecaldav: true # 设置每日消息（MOTD），通过 /info 接口可见 motd: "" # 是否允许通过链接共享项目 enablelinksharing: true # 是否允许新用户自行注册 enableregistration: true # 是否允许任务附件 enabletaskattachments: true # 所有时间戳使用的时区，需使用官方 tz 数据库名称（UTC/GMT 不可用） timezone: GMT # 是否启用任务评论 enabletaskcomments: true # 是否启用 TOTP 双因素认证 enabletotp: true # 如果不为空，将启用 /test/{table} 接口用于测试，可写入任意内容 # 非常危险，除非明确知道用途，否则不要启用 testingtoken: '' # 是否在任务到期时发送邮件提醒 enableemailreminders: true # 是否允许用户请求删除账号 enableuserdeletion: true # 用户头像最大尺寸（KB） maxavatarsize: 1024 # 是否显示演示模式警告（数据会被清空） demomode: false # 是否允许根据节日更换图标 allowiconchanges: true # 是否允许使用自定义 Logo customlogourl: '' # 是否启用公开团队功能，使团队可被发现 enablepublicteams: false sentry: # 是否启用 API 错误匿名跟踪（Sentry） enabled: false # 配置 Sentry DSN 用于 API 错误跟踪 dsn: "https://440eedc957d545a795c17bbaf477497c@o1047380.ingest.sentry.io/4504254983634944" # 是否启用前端错误匿名跟踪 frontendenabled: false # 配置 Sentry DSN 用于前端错误跟踪 frontenddsn: "https://85694a2d757547cbbc90cd4b55c5a18d@o1047380.ingest.sentry.io/6024480" database: # 数据库类型，可选 sqlite、mysql、postgres type: "sqlite" # 数据库用户名 user: "vikunja" # 数据库密码 password: "" # 数据库主机 host: "localhost" # 数据库名称 database: "vikunja" # 使用 sqlite 时数据库文件路径 path: "./vikunja.db" # 数据库最大打开连接数（仅 mysql/postgres） maxopenconnections: 100 # 数据库最大空闲连接数（仅 mysql/postgres） maxidleconnections: 50 # 单个数据库连接最大存活时间（毫秒） maxconnectionlifetime: 10000 # postgres 安全连接模式，可选 disable/require 等 sslmode: disable # postgres 客户端证书路径 sslcert: "" # postgres 客户端密钥路径 sslkey: "" # postgres 根证书路径 sslrootcert: "" # mysql 启用 SSL/TLS，可选 false/true/skip-verify/preferred tls: false typesense: # 是否启用 Typesense 集成，启用后所有任务通过 Typesense 搜索 enabled: false # Typesense 实例 URL url: '' # Typesense API key apikey: '' redis: # 是否启用 Redis enabled: false # Redis 服务器地址和端口 host: 'localhost:6379' # Redis 密码 password: '' # 使用的数据库编号（0 为默认） db: 0 cors: # 是否启用 CORS 头 enable: false # 允许访问 API 的来源列表（需包含协议 http:// 或 https://） origins: - "*" # 预检请求结果缓存时间（秒） maxage: 0 mailer: # 是否启用邮件功能，禁用后用户注册立即生效且无法重置密码 enabled: true # SMTP 主机 host: "smtp.qq.com" # SMTP 端口（若遇 EOF 错误可尝试改为 25） port: 465 # SMTP 验证类型，可选 plain、login、cram-md5 authtype: "plain" # SMTP 用户名 username: "11111111@qq.com" # SMTP 密码 password: "11111111" # 是否跳过 TLS 验证 skiptlsverify: false # 默认发件人邮箱 fromemail: "11111111@qq.com" # 邮件队列长度 queuelength: 100 # 邮件连接超时时间（秒） queuetimeout: 30 # 是否强制使用 SSL forcessl: true log: # 日志文件保存目录 path: /opt/vikunja/log/ # 是否启用日志 enabled: true # 普通日志输出方式，可选 stdout/stderr/file/off standard: "stdout" # 日志级别，可选 CRITICAL/ERROR/WARNING/NOTICE/INFO/DEBUG level: "INFO" # 是否记录数据库查询（调试用），可选 stdout/stderr/file/off database: "off" databaselevel: "WARNING" # 是否记录 HTTP 请求 http: "stdout" # Echo 日志，通常不需要 echo: "off" # 是否记录事件日志 events: "off" eventslevel: "info" # 是否记录邮件相关日志 mail: "off" maillevel: "info" ratelimit: # 是否启用速率限制 enabled: false # 速率限制类型，可选 user 或 ip kind: user # 限制周期（秒） period: 60 # 单位周期最大请求数 limit: 100 # 计数存储方式，可选 keyvalue/memory/redis store: keyvalue # 未认证用户每分钟访问限制（登录、注册、密码重置等接口） noauthlimit: 10 files: # 文件存储路径 basepath: ./files # 相对于二进制文件 # 文件最大体积 maxsize: 20MB migration: todoist: # 是否启用 Todoist 导入 enable: false # Todoist API client id clientid: # Todoist API client secret clientsecret: # 授权后回调 URL redirecturl: <service.publicurl>/migrate/todoist trello: # 是否启用 Trello 导入 enable: false key: redirecturl: <frontend url>/migrate/trello microsofttodo: # 是否启用 Microsoft ToDo 导入 enable: false clientid: clientsecret: redirecturl: <frontend url>/migrate/microsoft-todo avatar: # 使用 Gravatar 时缓存过期时间（秒） gravatarexpiration: 3600 backgrounds: # 是否启用项目背景 enabled: true providers: upload: # 是否允许上传背景 enabled: true unsplash: # 是否允许 Unsplash 背景 enabled: false accesstoken: applicationid: legal: # 法律相关 URL，会显示在前端 imprinturl: privacyurl: keyvalue: # 键值存储类型，可选 memory 或 redis type: "memory" auth: # 本地认证设置 local: enabled: true # OpenID 第三方认证 openid: enabled: false providers: - name: authurl: logouturl: clientid: clientsecret: scope: openid email profile metrics: # 是否启用 Prometheus /metrics 端点 enabled: false username: password: defaultsettings: # 新用户默认设置 avatar_provider: initials avatar_file_id: 0 email_reminders_enabled: false discoverable_by_name: false discoverable_by_email: false overdue_tasks_reminders_enabled: true overdue_tasks_reminders_time: 9:00 default_project_id: 0 week_start: 0 language: zh-CN timezone: Asia/Shanghai webhooks: # 是否启用 Webhooks enabled: true timeoutseconds: 30 proxyurl: proxypassword: 保存并退出 ：wq 查看配置文件名称是否正确，配置文件名称为config.yml 测试启动 确定配置文件名称没问题后，测试一下是否可以正常启动，启动后没报错就是成功了 ./vikunja 这时候我们使用浏览器访问服务器地址加端口号就可以看到登录页面了 配置开机自启 只要看到登录页面就是正常了，接下来就是配置开机自启了 首先按【Ctrl】+【c】停止 然后进入服务文件目录 cd /etc/systemd/system 创建一个.service文件 vi vikunja.service 把下面内容根据自己实际情况修改，然后粘贴进去，注意把注释全部删掉 [Unit] Description=Vikunja After=syslog.target network.target Requires=postgresql.service # 根据实际数据库选择 #Requires=mysql.service #Requires=redis.service [Service] Type=simple WorkingDirectory=/opt/vikunja # 二进制文件所在目录路径 ExecStart=/opt/vikunja/vikunja #二进制文件路径 Restart=always RestartSec=2s [Install] WantedBy=multi-user.target 保存并退出 修改文件权限 chmod +x vikunja.service 刷新system文件 sudo systemctl daemon-reload 启动vikunja systemctl start vikunja.service 设置开机自启 systemctl enable vikunja.service 使用 第一次登录 vikunja是没有默认管理员账号密码的，第一次登录是需要先注册一个账号密码 而且vikunja是没有管理员的，所有用户注册后就是普通用户，想要修改配置等都需要手动修改config文件 创建待办任务 点击【项目】 点击【新建项目】 输入标题，然后点击【创建】 这样一个大项目就创建好了，可以在这个大项目下面创建小项目 点击大项目旁边的三个点，然后点击【创建项目】 输入项目标题，然后点击【创建】 这样就创建好小项目了 接下来创建任务 点击项目名称，然后输入任务名称，点击【添加】 任务创建好后需要设置任务，点击任务右边的两条杠 在里面设置任务内容，时间等 更新 首先进行备份，备份当前版本的二进制文件 只需将二进制文件替换为新版本，然后重新启动 Vikunja。它将自动运行所有必要的数据库迁移。 请务必查看新版本的更新日志，以免错过更新过程中可能涉及的任何手动步骤！
简介 系统名称：ezbookkeeping 这个系统是再github上开源的，完全免费，没有会员广告限制，所有数据全部存储在自己的服务器上 功能方面也是比较全面的，除了基础的收支记录，账户管理，报表等功能外，还支持账单一键导入，可以导入支付宝微信账单，也可以导入银行账单 项目/下载地址 项目地址：https://github.com/mayswind/ezbookkeeping 也可以前往资源库搜索下载，本站提供linux1.0.1版本下载 搭建环境 这个系统支持子啊windows、linux等系统上运行 我这边使用的是linux系统 第一步：下载ezbookkeeping 打开项目地址 点击顶部的标签 点击最新的版本号 找到适合自己处理器和系统的版本，右键复制链接地址 使用SSH连接到自己服务器，在/opt目录下创建一个新文件夹 mkdir /opt/ezbookkeeping 进入刚刚创建的文件夹 cd ezbookkeeping 使用wget命令下载 wget 刚刚复制的下载链接 wget https://github.com/mayswind/ezbookkeeping/releases/download/v1.0.1/ezbookkeeping-1.0.1-linux-amd64.tar.gz 解压下载的文件 tar -zxvf ezbookkeeping-1.0.1-linux-amd64.tar.gz 第二步：测试运行 解压出来后，可以看到有一堆文件，其中里面有个文件名为ezbookkeeping，这个就是这个系统的二进制运行文件，使用下面命令测试运行 ./ezbookkeeping server run 使用浏览器访问服务器地址加8080端口，如果正常的话会打开登录界面 第三步：设置开机自启 可以正常运行后就没问题了，接下来就是配置开机自启了 进入system服务 cd /etc/systemd/system 使用vi编辑器新建一个文件 vi ezbookkeeping.service 把下面内容复制站体进去，记得根据自己实际情况修改路径 [Unit] Description=ezBookkeeping Server After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/ezbookkeeping ExecStart=/opt/ezbookkeeping/ezbookkeeping server run Restart=on-failure StandardOutput=append:/opt/ezbookkeeping/log/ezbookkeeping.log StandardError=append:/opt/ezbookkeeping/log/ezbookkeeping.log [Install] WantedBy=multi-user.target 修改完成后保存并退出，然后授权可执行权限 刷新system配置文件 systemctl daemon-reload 启动 systemctl start ezbookkeeping 设置开机自启 systemctl enable ezbookkeeping.service 修改配置文件（可选） ezbookkeeping并没有管理员账户，然后用管理员账户修改系统配置，新增删除账户之类的，所有的配置都需要直接修改配置文件 修改配置文件可以参考官方的手册来修改 官方手册地址：https://ezbookkeeping.mayswind.net/zh_Hans 例如我需要关掉用户可以注册 首先我先看一下官方的手册，找到关于用户注册的 然后打开配置文件 vi conf/ezbookkeeping.ini 然后找到刚刚我们查询手册上对应的选项名 现在是true就是启用，要关闭就改成false，修改完成后保存退出 然后重启服务 systemctl restart ezbookkeeping.service 再次打开就可以看到创建用户点击不了了 注意事项 该项目没有管理界面，所有管理都需要命令行实现，要么修改配置文件要么使用命令 具体配置以及命令可以参考官方手册 喜欢折腾的可以研究看看 更新 使用二进制文件部署的，更新的时候下载最新版的包解压，然后覆盖原来的二进制文件ezbookkeeping和public目录以及templates目录即可 不要替换 conf/、data/、log/、storage/目录， conf目录存放配置文件 data目录存放数据库 log目录存放日志 storage目录存放用户上传的文件 更新完成后进入到二进制文件目录，执行更新数据数据库结构操作 命令： ./ezbookkeeping database update
简介 之前我的博客和服务器上的其他系统都是我手动备份数据的，因为懒，所以懒得整自动备份 最近连手动备份也懒了，想想还是整个自动备份吧 我使用的工具是restic是本地/远程备份工具，可以实现增量备份 + 去重 + 压缩 + 加密 + 快照管理 可以把数据备份到 本地磁盘、NAS、SFTP、S3 等支持的后端 功能 描述 增量备份 每次只保存变化的数据，节省空间 去重 不同备份间重复数据只保存一次 压缩 数据存储时自动压缩，节省存储空间 加密 备份自动加密，保证安全 快照管理 可以查看、保留、删除历史版本 跨平台 Linux / Windows / macOS 都支持 思路 我的服务器使用的是联想M73，只有一个硬盘位，所以打算外接一个USB硬盘来存储备份文件 刚开始想使用网盘进行备份的，后面发现很多网盘备份工具都不知此个人版的网盘，只支持企业版，当然也不是没有办法，先把网盘挂载成webdav，然后存进去就可以了 但是我懒，反正家里面有硬盘 第一步：格式化硬盘 首先把USB硬盘插上去，然后使用下面命令查看硬盘信息，可以看到这里已经读出我的硬盘了，是/dev/sdc1 lsblk -f 硬盘格式是ntfs，这个格式对linux并不友好，我需要格式化成ext4格式 首先卸载硬盘，如果没有挂载的话就忽略这一步，如果不知道硬盘有没有挂载就直接执行也没事，没有挂载会有提示 umount /dev/sdc1 然后格式化硬盘，中间可能会弹出提示，输入y回车继续 mkfs.ext4 -L backup /dev/sdc1 等待完成 第二步：挂载硬盘 使用下面命令查看确定硬盘的UUID，记得把UUID复制下来 blkid /dev/sdc1 使用vi编辑下面文件 vi /etc/fstab 在文件最后面添加挂载信息，把下面这一行复制修改UUID为你硬盘的UUID，ntfs-3g改成硬盘格式，然后粘贴到文件的最后面，因为是移动硬盘，所以我们加了nofail,x-systemd.device-timeout=10，这个是开机等待10秒，不管有没有检测到这个设备都直接开机，如果不加的话移动硬盘出现问题挂载不了就会导致开机卡住，开不了机 UUID=068273068272FA0F /mnt/usb ntfs-3g defaults,nofail,x-systemd.device-timeout=10 0 0 添加完成后，保存退出 执行立即挂载命令，但是我这提示挂载失败，挂载点不存在 mount -a 这个是因为我的系统里面没有/mnt/usb这个目录，所以挂载不上，我先创建一个/mnt/usb目录 mkdir /mnt/usb 然后再次执行挂载命令，提示不是错误，只是 systemd 在提醒：你修改了 /etc/fstab，但 systemd 还缓存着旧配置。 不过 mount -a 是直接读 /etc/fstab 的，不依赖 systemd，所以已经生效了 mount -a 使用下面命令查看是否挂载成功，看到有挂载点就是成功了 lsblk -f 使用下面命令让 systemd 下次启动时用新的配置 systemctl daemon-reload 第三步：下载release release可以直接使用系统源yum、apt下载，但是版本比较老，我是直接去github项目地址下载的 项目地址：https://github.com/restic/restic/ 首先创建一个文件夹，用来存放release的二进制运行文件 mkdir /opt/release 进入刚刚创建的文件夹 cd /opt/release 进入release项目地址 点击顶部的标签 点击最新的版本号 滑倒下面，找到对应自己服务器操作系统和处理器的版本，右键，复制链接地址 回到SSH终端，使用wget命令下载 wget https://github.com/restic/restic/releases/download/v0.18.1/restic_0.18.1_linux_amd64.bz2 下载完成后解压出来，然后使用ls命令查看解压出来的文件 bunzip2 restic_0.18.1_linux_amd64.bz2 ls 解压出来的文件名太长了，我们重命名一下 mv restic_0.18.1_linux_amd64 restic 修改文件权限，让文件可执行 chmod +x restic 第四步：创建备份文件列表 使用vi编辑器创建一个txt文件，名称为：backup_dirs.txt vi backup_dirs.txt 然后把需要备份的文件目录写进去，这样后面我们需要增加或者删除备份目录就直接修改这个文件列表即可 /home/wwwroot/www.ersansi.top /root/Dufs-data /usr/local/frpc /usr/local/hysteria2 /root/mysql-bak-up 编辑完成后保存并退出 第五步：初始化备份仓库 我们先在刚刚挂载的USB移动硬盘上创建一个文件夹，用于存放备份文件 mkdir -p /mnt/usb/restic-repo 在创建一个密码文件，用于存储备份加密密码，这个密码很重要，恢复备份的时候也需要这个密码 echo "你的备份密码" > /opt/release/.restic-passwd 修改文件权限 chmod 600 .restic-passwd 初始化仓库，看到下图的结果就是初始化成功了 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd init 第六步：测试备份 使用下面命令测试一下是否可以正常备份,backup后面就是你需要备份的文件目录路径 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd backup 你的需要备份的文件路径 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd backup /usr/local/frpc 看最后一行，快照ID是1c0a9736，说明备份成功了 查看一下快照内容 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd snapshots 测试还原 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd restore 快照ID --target 需要还原到的目录 /opt/release/restic -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd restore 1c0a9736 --target /root/test-restore 可以看到也是可以正常还原的 第七步：创建脚本 因为我的备份有mysql，我需要先把数据库导出来，然后再进行备份，所以我需要一个脚本来导出数据库，数据库导出成功后才能备份 首先创建一个.sh文件 vi full-backup.sh 然后把下面内容复制修改一下粘贴到里面 #!/bin/bash # ------------------------------- # 全量备份 MySQL + 文件到 Restic # ------------------------------- # ---------------- MySQL 配置 ---------------- MYSQL_USER="数据库用户名" MYSQL_PASSWORD="数据库密码" MYSQL_HOST="数据库地址" MYSQL_BACKUP_DIR="导出到的文件目录路径" DB_TO_BACKUP="需要导出的数据库，需要导出所有则去掉引号输入0" EMAIL="接收邮件的邮箱，需要安装对应服务才能使用发送邮件功能" # ---------------- Restic 配置 ---------------- RESTIC_BIN="restic二进制文件路径" RESTIC_REPO="需要备份到的仓库路径" RESTIC_PASSWORD_FILE="密码文件路径" BACKUP_DIRS_FILE="备份列表路径" mkdir -p "$MYSQL_BACKUP_DIR" send_mail() { local subject="$1" local body="$2" echo -e "$body" | mail -s "$subject" -r "服务器备份 <发送邮件的邮箱>" "$EMAIL" } # ---------------- 1. MySQL 备份 ---------------- if [ "$DB_TO_BACKUP" == "0" ]; then DBS=$(/usr/bin/mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)") else DBS="$DB_TO_BACKUP" fi for db in $DBS; do echo "备份数据库: $db" if ! /usr/bin/mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" "$db" > "$MYSQL_BACKUP_DIR/$db.sql"; then echo "[$(date)] 数据库 $db 导出失败" >&2 send_mail "MySQL 备份失败" "数据库 $db 导出失败，请检查服务器" exit 1 fi done echo "MySQL 备份成功: $(date)" # ---------------- 2. Restic 备份 ---------------- echo "开始 Restic 备份..." if ! $RESTIC_BIN -r "$RESTIC_REPO" --password-file "$RESTIC_PASSWORD_FILE" backup --files-from "$BACKUP_DIRS_FILE"; then echo "[$(date)] Restic 备份失败" >&2 send_mail "Restic 备份失败" "文件备份失败，请检查服务器" exit 1 fi echo "Restic 备份完成: $(date)" send_mail "备份成功" "MySQL + 文件备份成功完成！" 编辑完成后保存退出，然后授权文件可执行 chmod +x full-backup.sh 执行测试一下是否可用 ./full-backup.sh 第七步：创建服务 测试脚本成功了，接下来就是创建system的任务文件了 vi /etc/systemd/system/full-backup.service 把下面内容复制粘贴进去，记得把路径改成自己脚本所在的路径 [Unit] Description=全量备份 MySQL + 文件 After=network.target [Service] Type=oneshot ExecStart=/opt/release/full-backup.sh StandardOutput=journal StandardError=journal RemainAfterExit=no [Install] WantedBy=multi-user.target 编辑完成后保存并退出，然后修改权限为可执行权限 第八步：创建定时器 上面创建了服务，用来运行sh脚本，但是我们还需要一个定时器来触发服务，这样就可以实现再指定的时间断进行备份了 vi /etc/systemd/system/full-backup.timer 然后把下面内容复制粘贴进去 [Unit] Description=每天凌晨 3 点执行全量备份 [Timer] Unit=full-backup.service OnCalendar=*-*-* 03:00:00 Persistent=true [Install] WantedBy=timers.target OnCalendar=-- 03:00:00 表示每天的 03:00:00 运行（-- 代表任意年-月-日） Persistent=true 如果机器在 03:00 没开机，开机后会立即补跑一次（防止错过） 编辑好后保存并退出，然后修改权限为可执行 chmod +x /etc/systemd/system/full-backup.timer 第九步：应用配置 所有文件全部配置好后，我们就可以应用配置了 首先重载一下systemd配置文件 systemctl daemon-reload 然后设置定时器开机就启动 systemctl enable full-backup.timer 最后手动启动定时器 systemctl start full-backup.timer 启动完成后我们可以执行下面命令查看定时任务 systemctl list-timers --all restic命令 为了方便理解，我这里列一下文件路径 restic二进制文件路径：/opt/release/restic 仓库路径：/mnt/usb/restic-repo 密码文件路径：/opt/release/.restic-passwd 备份列表文件路径：/opt/release/backup_dirs.txt 快照ID：1d0ce954 恢复目标目录：/root/bakup 快照挂载点：/usr/local/frpc 初始化仓库 第一次备份的时候需要先初始化仓库，后面不需要 restic路径 init -r 仓库路径 --password-file 密码文件路径 套入我上面的路径就是下面命令 /opt/release/restic init -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 备份目录 直接指定备份目录： restic路径 backup 需要备份的目录 -r 仓库路径 --password-file 密码文件路径 指定备份文件列表文件： restic路径 backup --files-from 列表文件路径 -r 仓库路径 --password-file 密码文件路径 替换成我上面的文件文件路径 /opt/release/restic backup --files-from /opt/release/backup_dirs.txt -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 列出所有快照 restic路径 snapshots -r 仓库路径 --password-file 密码文件路径 替换成我上面的路径 /opt/release/restic snapshots -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 查看仓库状态 restic路径 stats -r 仓库路径 --password-file 密码文件路径 替换成我上面的路径 /opt/release/restic stats -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 查看快照详细文件列表 restic路径 ls 快照ID -r /仓库路径 --password-file /密码文件路径 替换成我上面的路径 /opt/release/restic ls 1d0ce954 -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 恢复快照到指定目录 restic路径 restore 快照ID -r 仓库路径 --password-file 密码文件路径 --target 恢复目标目录 替换成我上面的路径 /opt/release/restic restore 1d0ce954 -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd --target /root/bakup 恢复指定快照中的指定目录 例如我现在备份仓库中有很多目录，我只需要恢复其中一个目录，不需要恢复整个快照，那是可以直接指定恢复的目录的 下面示例是我只需要恢复快照id为1d0ce954的里面的etc目录 restic路径 restore 快照ID -r 仓库路径 --password-file 密码文件路径 --target 需要恢复到的路径 --include 需要恢复的目录 替换成上面的路径： /opt/release/restic restore 快照ID -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd --target /tmp/restore --include /etc 恢复指定快照中的指定文件 restic路径 restore 快照ID -r 仓库路径 --password-file 密码文件路径 --target 需要恢复到的路径 --include 需要恢复的文件路径 只把 /etc下的hosts 恢复到 /tmp/restore/etc /opt/release/restic restore 1d0ce954 -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd --target /tmp/restore --include /etc/hosts 排除一些目录，只恢复其他内容 restic路径 restore 快照ID -r 仓库路径 --password-file 密码文件路径 --target 需要恢复到的路径 --include 需要恢复的目录 --exclude 需要排除的目录路径 比如只恢复 /home，但不要 /home/cache /opt/release/restic restore d0ce954 -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd --target /tmp/restore --include /home --exclude /home/cache 清理未引用的数据（垃圾回收） restic路径 forget --prune -r 仓库路径 --password-file 密码文件路径 替换成上面路径 /opt/release/restic forget --prune -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 设置保留策略（例如：保留最近 7 天的备份） restic路径 forget --keep-daily 7 --prune -r 仓库路径 --password-file 密码文件路径 替换成上面路径： /opt/release/restic forget --keep-daily 7 --prune -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 校验备份完整性 restic路径 check -r 仓库路径 --password-file 密码文件路径 替换成上面路径： /opt/release/restic check -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 挂载快照（FUSE，需要 Linux） restic路径 mount 挂载点 -r 仓库路径 --password-file 密码文件路径 替换成上面路径： /opt/release/restic mount /usr/local/frpc -r /mnt/usb/restic-repo --password-file /opt/release/.restic-passwd 删除指定快照 restic路径 -r 仓库路径 forget <快照ID1> --prune --password-file 密码文件路径 替换成上面路径 /opt/release/restic -r /mnt/usb/restic-repo forget 1d0ce954 --prune --password-file /opt/release/.restic-passwd 如果有多个快照ID则用空格隔开 restic菜单脚本 我还做了一个菜单脚本，方便使用restic，需要的可以下载把里面的环境参数修改一下即可使用 下面是菜单脚本的内容，记得把上面的环境变量修改和自己相符的 #!/bin/bash # 配置 RESTIC_BIN="restic二进制文件路径" REPO="仓库路径" PASSFILE="密码文件路径" RESTORE_TARGET="默认的快照恢复目标目录" DEFAULT_MOUNT="默认挂载快照的目录" FULL_BACKUP="备份脚本路径" # 检查 restic 和 full-backup.sh 是否存在 if [ ! -x "$RESTIC_BIN" ]; then echo "错误: Restic 未找到，请检查路径: $RESTIC_BIN" exit 1 fi if [ ! -x "$FULL_BACKUP" ]; then echo "错误: full-backup.sh 未找到或不可执行: $FULL_BACKUP" exit 1 fi # 通用暂停函数 function pause() { echo read -p "按 Enter 返回菜单..." } # 显示快照列表 function show_snapshots() { clear echo "=== 快照列表 ===" $RESTIC_BIN snapshots -r $REPO --password-file $PASSFILE | less -SFXR echo "================" pause } # 显示快照文件列表 function show_snapshot_files() { show_snapshots read -p "请输入快照ID查看文件: " SNAPSHOT_ID clear echo "=== 快照 $SNAPSHOT_ID 文件列表 ===" $RESTIC_BIN ls $SNAPSHOT_ID -r $REPO --password-file $PASSFILE | less -SFXR echo "================" pause } # 菜单循环 while true; do clear echo "=====================================" echo " Restic 备份管理菜单" echo " 仓库: $REPO" echo " 密码文件: $PASSFILE" echo "=====================================" echo " 1) 初始化仓库" echo " 2) 执行完整备份 (full-backup.sh)" echo " 3) 查看快照列表" echo " 4) 查看仓库状态" echo " 5) 查看快照文件内容" echo " 6) 恢复快照 (支持指定目录/文件)" echo " 7) 删除旧快照并清理" echo " 8) 校验仓库完整性" echo " 9) 挂载快照 (浏览文件)" echo "10) 卸载快照" echo "11) 手动执行 forget/keep 策略" echo " 0) 退出" echo "=====================================" read -p "请选择操作: " choice case $choice in 1) echo "⚠️ 初始化仓库会清空原有数据，仅首次使用时需要执行！" read -p "确认初始化仓库？(yes/no): " confirm if [ "$confirm" == "yes" ]; then $RESTIC_BIN init -r $REPO --password-file $PASSFILE else echo "已取消。" fi pause ;; 2) echo "开始完整备份..." if "$FULL_BACKUP"; then echo "备份完成。" else echo "备份失败，请检查 full-backup.sh 日志。" fi pause ;; 3) show_snapshots ;; 4) clear echo "=== 仓库状态 ===" $RESTIC_BIN stats -r $REPO --password-file $PASSFILE | less -SFXR echo "================" pause ;; 5) show_snapshot_files ;; 6) show_snapshots read -p "请输入快照ID: " SNAPSHOT_ID read -p "请输入要恢复的路径(例如 /etc，留空恢复全部): " INCLUDE_PATH read -p "请输入恢复目标目录(默认 $RESTORE_TARGET): " TARGET TARGET=${TARGET:-$RESTORE_TARGET} mkdir -p "$TARGET" if [ -z "$INCLUDE_PATH" ]; then $RESTIC_BIN restore $SNAPSHOT_ID -r $REPO --password-file $PASSFILE --target "$TARGET" else $RESTIC_BIN restore $SNAPSHOT_ID -r $REPO --password-file $PASSFILE --target "$TARGET" --include "$INCLUDE_PATH" fi echo "恢复完成，文件在: $TARGET" pause ;; 7) read -p "请输入保留的天数(默认7): " DAYS DAYS=${DAYS:-7} echo "模拟执行: 将显示哪些快照会被删除 (dry-run)" $RESTIC_BIN forget --keep-daily $DAYS --prune --dry-run -r $REPO --password-file $PASSFILE | less -SFXR read -p "确认执行删除？(yes/no): " CONFIRM if [ "$CONFIRM" == "yes" ]; then $RESTIC_BIN forget --keep-daily $DAYS --prune -r $REPO --password-file $PASSFILE echo "清理完成。" else echo "已取消清理。" fi pause ;; 8) clear echo "校验仓库完整性..." $RESTIC_BIN check -r $REPO --password-file $PASSFILE | less -SFXR pause ;; 9) read -p "请输入挂载目录(默认 $DEFAULT_MOUNT): " MOUNT_DIR MOUNT_DIR=${MOUNT_DIR:-$DEFAULT_MOUNT} mkdir -p "$MOUNT_DIR" echo "挂载中... 浏览路径: $MOUNT_DIR" $RESTIC_BIN mount "$MOUNT_DIR" -r $REPO --password-file $PASSFILE & echo "已挂载，可用 'fusermount -u $MOUNT_DIR' 卸载。" pause ;; 10) read -p "请输入要卸载的目录(默认 $DEFAULT_MOUNT): " MOUNT_DIR MOUNT_DIR=${MOUNT_DIR:-$DEFAULT_MOUNT} fusermount -u "$MOUNT_DIR" 2>/dev/null || umount "$MOUNT_DIR" echo "已卸载 $MOUNT_DIR" pause ;; 11) echo "执行自定义 forget 策略示例:" echo "保留最近7天, 4周, 12月, 每年1个快照" read -p "模拟执行查看将删除哪些快照？(yes/no): " DRYRUN if [ "$DRYRUN" == "yes" ]; then $RESTIC_BIN forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 1 --prune --dry-run -r $REPO --password-file $PASSFILE | less -SFXR fi read -p "确认执行实际删除？(yes/no): " CONFIRM if [ "$CONFIRM" == "yes" ]; then $RESTIC_BIN forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 1 --prune -r $REPO --password-file $PASSFILE echo "删除完成。" else echo "已取消删除。" fi pause ;; 0) echo "退出菜单。" exit 0 ;; *) echo "无效选择，请重试。" pause ;; esac done 也可以前往资源库搜索下载 新full-backup.sh脚本 之前的脚本功能比较简单，所以更新了一下脚本 MySQL 数据库备份 支持备份单个数据库、多数据库或全部数据库（排除系统库）。 严格检查备份完整性： 捕获 mysqldump 返回码和错误输出。 能区分错误类型： 用户名或密码错误 → “连接数据库失败（用户名或密码错误）” 数据库不存在 → “数据库不存在” 无法连接 MySQL 主机/端口 → “无法连接数据库（主机或端口错误）” 其他未知错误 → “未知错误（请检查数据库是否存在或权限是否正确）” 如果有任何数据库导出失败： 会将所有失败的数据库和原因汇总在邮件中。 立即停止脚本执行，确保数据完整性。 成功导出数据库会生成 .sql 文件，并显示文件大小（MB/GB）。 文件/目录备份 支持通过 backup_dirs.txt 列表备份任意目录。 严格检查目录存在性： 在开始备份前逐个检查目录是否存在且可访问。 若发现目录不存在或不可访问： 立即停止备份。 发送邮件通知，并列出出错目录。 使用 Restic 进行备份。 捕获 Restic 输出，若失败立即停止并发送详细邮件。 每个目录备份完成后，会统计并记录大小。 总备份大小统计 使用 Restic stats --mode raw-data --last 1 获取最新快照的实际数据大小。 自动将字节转换为 MB 或 GB 显示，确保总备份大小准确。 快照 ID 获取最新 Restic 快照的短 ID 并显示，便于后续恢复或管理。 邮件通知 支持成功和失败邮件通知。 失败邮件： 包含 MySQL 导出失败详情或文件目录备份失败目录。 成功邮件： 列出所有 MySQL 数据库导出文件及大小。 列出所有备份目录及大小。 总备份大小、快照 ID、备份开始和结束时间、耗时。 进度与日志 控制台输出详细进度： MySQL 每个数据库导出情况。 文件/目录备份列表。 每个文件/目录的大小。 方便用户监控备份状态。 数据完整性保证 严格模式： 任何数据库导出失败或文件目录备份失败，脚本立即停止。 避免不完整备份进入 Restic 仓库。 邮件提供详细失败信息，便于快速定位问题。 脚本内容 #!/bin/bash # ------------------------------- # 全量备份 MySQL + 文件到 Restic # ------------------------------- # 作者：贰叁肆博客 # ------------------------------- # ---------------- 配置 ---------------- # MySQL 配置 MYSQL_USER="数据库用户名" MYSQL_PASSWORD="数据库密码" MYSQL_HOST="数据库地址" MYSQL_BACKUP_DIR="导出路径" DB_TO_BACKUP=数据库名" # 0表示备份所有数据库，多个用空格隔开 # 邮件配置 EMAIL="收件地址" MAIL_ENABLE=true # 邮件通知开关 true/false # Restic 配置 RESTIC_BIN="restic二进制文件路径" RESTIC_REPO="备用仓库路径" RESTIC_PASSWORD_FILE="密码文件路径" BACKUP_DIRS_FILE="备份列表文件路径" mkdir -p "$MYSQL_BACKUP_DIR" # ---------------- 邮件发送函数 ---------------- send_mail() { if [ "$MAIL_ENABLE" = true ]; then local subject="$1" local body="$2" echo -e "$body" | mail -s "$subject" -r "服务器备份 <发件邮箱>" "$EMAIL" fi } # ---------------- 开始计时 ---------------- START_TIME=$(date +%s) BACKUP_START=$(date '+%Y-%m-%d %H:%M:%S') # ---------------- 1. MySQL 备份 ---------------- FAILED_DBS=() DB_SIZE_INFO="" if [ "$DB_TO_BACKUP" == "0" ]; then DBS=$(/usr/bin/mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)") else DBS="$DB_TO_BACKUP" fi for db in $DBS; do echo "==== 开始备份数据库: $db ====" echo "正在导出数据库 $db ..." # 捕获 mysqldump 输出和返回码 DUMP_OUTPUT=$(/usr/bin/mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" "$db" 2>&1) EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then rm -f "$MYSQL_BACKUP_DIR/$db.sql" if echo "$DUMP_OUTPUT" | grep -q "Access denied"; then FAIL_REASON="连接数据库失败（用户名或密码错误）" elif echo "$DUMP_OUTPUT" | grep -q "Unknown database"; then FAIL_REASON="数据库不存在" elif echo "$DUMP_OUTPUT" | grep -q "Can't connect to MySQL server" || \ echo "$DUMP_OUTPUT" | grep -q "Lost connection to MySQL server"; then FAIL_REASON="无法连接数据库（主机或端口错误）" else FAIL_REASON="$DUMP_OUTPUT" fi FAILED_DBS+=("$db : $FAIL_REASON") continue fi echo "$DUMP_OUTPUT" > "$MYSQL_BACKUP_DIR/$db.sql" SIZE_BYTES=$(stat -c%s "$MYSQL_BACKUP_DIR/$db.sql" 2>/dev/null) SIZE_BYTES=${SIZE_BYTES:-0} if [ "$SIZE_BYTES" -ge 1073741824 ]; then SIZE_FMT=$(awk "BEGIN{printf \"%.2f GB\", $SIZE_BYTES/1024/1024/1024}") else SIZE_FMT=$(awk "BEGIN{printf \"%.2f MB\", $SIZE_BYTES/1024/1024}") fi echo "数据库 $db 导出完成，文件大小: $SIZE_FMT" DB_SIZE_INFO+="$db.sql : $SIZE_FMT\n" done if [ ${#FAILED_DBS[@]} -ne 0 ]; then FAIL_STEP="以下数据库导出失败:\n$(printf "%s\n" "${FAILED_DBS[@]}")" send_mail "MySQL 备份失败" "备份失败步骤:\n$FAIL_STEP\n请检查数据库连接或权限。" exit 1 fi echo "==== MySQL 备份完成 ====" # ---------------- 2. Restic 备份 ---------------- echo "==== 开始 Restic 备份 ====" echo "备份目录/文件列表:" cat "$BACKUP_DIRS_FILE" echo "------------------------" if ! $RESTIC_BIN -r "$RESTIC_REPO" --password-file "$RESTIC_PASSWORD_FILE" \ backup --files-from "$BACKUP_DIRS_FILE" --verbose 2>&1 | tee /tmp/restic-backup.log; then send_mail "Restic 备份失败" "备份失败步骤: Restic 文件备份失败\n详细信息:\n$(cat /tmp/restic-backup.log)" exit 1 fi echo "==== Restic 备份完成 ====" # ---------------- 3. 目录大小信息 ---------------- DIR_SIZE_INFO="" while IFS= read -r line; do if [ -e "$line" ]; then SIZE_BYTES=$(du -sb "$line" 2>/dev/null | awk '{print $1}') SIZE_BYTES=${SIZE_BYTES:-0} if [ "$SIZE_BYTES" -ge 1073741824 ]; then SIZE_FMT=$(awk "BEGIN{printf \"%.2f GB\", $SIZE_BYTES/1024/1024/1024}") else SIZE_FMT=$(awk "BEGIN{printf \"%.2f MB\", $SIZE_BYTES/1024/1024}") fi DIR_SIZE_INFO+="$line : $SIZE_FMT\n" else DIR_SIZE_INFO+="$line : 不存在\n" fi done < "$BACKUP_DIRS_FILE" # ---------------- 4. 成功邮件信息 ---------------- END_TIME=$(date +%s) BACKUP_END=$(date '+%Y-%m-%d %H:%M:%S') ELAPSED_TIME=$((END_TIME-START_TIME)) # 获取本次备份总大小 (使用 restore-size) BACKUP_SIZE_BYTES=$($RESTIC_BIN -r "$RESTIC_REPO" --password-file "$RESTIC_PASSWORD_FILE" \ stats --json --mode restore-size latest | jq -r '.total_size // 0') if [ "$BACKUP_SIZE_BYTES" -ge 1073741824 ]; then BACKUP_SIZE=$(awk "BEGIN{printf \"%.2f GB\", $BACKUP_SIZE_BYTES/1024/1024/1024}") else BACKUP_SIZE=$(awk "BEGIN{printf \"%.2f MB\", $BACKUP_SIZE_BYTES/1024/1024}") fi SNAPSHOT_ID=$($RESTIC_BIN -r "$RESTIC_REPO" --password-file "$RESTIC_PASSWORD_FILE" \ snapshots --json | jq -r 'sort_by(.time)[-1].short_id') MAIL_BODY="备份成功！ === MySQL 导出文件 === $DB_SIZE_INFO === 文件/目录备份 === $DIR_SIZE_INFO 总备份大小: $BACKUP_SIZE 快照 ID: $SNAPSHOT_ID 开始时间: $BACKUP_START 结束时间: $BACKUP_END 耗时: ${ELAPSED_TIME}s " send_mail "备份成功" "$MAIL_BODY" echo "==== 备份完成 ====" echo "总耗时: ${ELAPSED_TIME}s"
简介 Navidrome 是一个轻量级的、自托管的音乐服务器，类似 Subsonic，但更加现代和开源。它可以让你在任何设备上访问和播放自己的音乐库，并支持转码、Web 界面、API 等多种功能。 支持linux部署和windows部署 地址 Github项目地址：https://github.com/navidrome/navidrome 官网地址：https://www.navidrome.org/ 官网手册地址：https://www.navidrome.org/docs/ 也可以从本站的资源库里面搜索下载，本站资源库提供的版本是linux-amd64版本 部署环境 操作系统：Almalinux 第一步：下载/解压Navidrome 下载 首先打开github项目地址 然后点击顶部的标签 点击最新的版本号 滑倒下面，找到对应自己服务器的版本，点击右键，复制链接地址 使用SSH工具链接服务器，然后使用下面命令创建文件夹 mkdir /opt/navidrome 进入刚刚创建的文件夹 cd /opt/navidrome 使用wgeet命令下载刚刚复制的链接的文件 wget https://github.com/navidrome/navidrome/releases/download/v0.58.0/navidrome_0.58.0_linux_amd64.tar.gz 下载完成后，使用ls命令查看刚刚下载的文件 ls 解压 使用tar命令解压刚刚下载的文件 tar -zxvf navidrome_0.58.0_linux_amd64.tar.gz 使用ls命令查看解压出来的文件 我们只需要保留navidrome这个文件就行，其他的直接使用rm命令删除 rm -f LICENSE navidrome_0.58.0_linux_amd64.tar.gz README.md 配置navidrome 使用vi命令创建一个配置文件 vi navidrome.toml 然后把下面配置内容根据自己需求修改一下，复制粘贴进去 # ========================================== # Navidrome 配置文件示例 (最全) # ========================================== # ------------------- # 服务器设置 # ------------------- Port = 4533 # Web界面端口 Address = "0.0.0.0" # 监听地址，0.0.0.0 表示所有网卡 BaseURL = "" # 如果部署在子目录，例如 /music LogLevel = "info" # 日志等级: debug / info / warn / error # ------------------- # 数据库设置 # ------------------- DataFolder = "/srv/navidrome/data" # 数据库和缓存文件存放目录 DBType = "sqlite3" # 数据库类型: sqlite3 / postgres DBPath = "navidrome.db" # sqlite 数据库文件路径（如果使用 sqlite3） # PostgreSQL 连接设置（如果 DBType=postgres） PostgresHost = "localhost" PostgresPort = 5432 PostgresUser = "navidrome" PostgresPassword = "password" PostgresDB = "navidrome" # ------------------- # 音乐库设置 # ------------------- MusicFolder = "/srv/navidrome/music" # 音乐文件目录，必须存在且可读写 ScanInterval = "5m" # 自动扫描音乐库的间隔，可设为 "10m"、"1h" AllowedExtensions = ["mp3", "flac", "ogg", "m4a"] # 支持的音频文件格式 FullScanOnStartup = true # 启动时是否执行全量扫描 PlaylistImport = true # 启动时是否导入已有播放列表 # ------------------- # 用户与安全 # ------------------- NoAuth = false # true 表示无需登录 SignupEnabled = true # 是否允许用户注册 AllowSignUpAdmin = false # 注册用户是否默认管理员，建议 false DefaultUserQuota = 0 # 用户配额，0表示无限 UserSessionQuota = 5 # 每个用户同时允许的会话数 SessionTimeout = "24h" # 会话过期时间 # ------------------- # 播放与转码 # ------------------- FFmpegPath = "/usr/local/bin/ffmpeg" # FFmpeg 可执行文件路径 Transcoding = true # 是否开启实时转码 MaxBitrate = 320 # 转码最大码率 kbps TranscodingCacheMaxSize = "100MB" # 转码缓存大小 AllowDownload = true # 是否允许客户端下载音乐 EnableCoverArt = true # 是否生成封面图 # ------------------- # API 设置 # ------------------- EnableSubsonic = true # 是否开启 Subsonic API SubsonicSalt = "随机字符串" # Subsonic API 密钥盐 EnableWebhooks = false # 是否开启 Webhooks 事件通知 EnableSpotify = false # 是否启用 Spotify 集成 SpotifyClientID = "" # Spotify Client ID SpotifyClientSecret = "" # Spotify Client Secret EnableLastFM = false # 是否集成 LastFM LastFMAPIKey = "" # LastFM API Key EnableListenBrainz = false # 是否集成 ListenBrainz ListenBrainzUsername = "" # ListenBrainz 用户名 ListenBrainzPassword = "" # ListenBrainz 密码 # ------------------- # 缓存设置 # ------------------- ImageCacheMaxSize = "100MB" # 封面图缓存大小 BackgroundCacheMaxSize = "100MB" # 背景缓存大小 # ------------------- # 高级与调试 # ------------------- Debug = false # 开启调试模式 EnableSSL = false # 如果你打算直接用 Navidrome 提供 HTTPS SSLCertFile = "/path/to/cert.pem" # SSL 证书路径 SSLKeyFile = "/path/to/key.pem" # SSL 私钥路径 下面是我的配置文件 # ------------------- # 服务器设置 # ------------------- Port = 4533 # Web界面端口 Address = "0.0.0.0" # 监听地址，0.0.0.0 表示所有网卡 BaseURL = "" # 如果部署在子目录，例如 /music LogLevel = "info" # 日志等级: debug / info / warn / error # ------------------- # 数据库设置 # ------------------- DataFolder = "/opt/navidrome/data" # 数据库和缓存文件存放目录 DBType = "sqlite3" # 数据库类型: sqlite3 / postgres DBPath = "/opt/navidrome/data/navidrome.db" # sqlite 数据库文件路径（如果使用 sqlite3） # ------------------- # 音乐库设置 # ------------------- MusicFolder = "/opt/navidrome/music" # 音乐文件目录，必须存在且可读写 ScanInterval = "5m" # 自动扫描音乐库的间隔，可设为 "10m"、"1h" AllowedExtensions = ["mp3", "flac", "ogg", "m4a"] # 支持的音频文件格式 FullScanOnStartup = true # 启动时是否执行全量扫描 PlaylistImport = true # 启动时是否导入已有播放列表 # ------------------- # 用户与安全 # ------------------- NoAuth = true # true 表示无需登录 SignupEnabled = false # 是否允许用户注册 AllowSignUpAdmin = false # 注册用户是否默认管理员，建议 false DefaultUserQuota = 0 # 用户配额，0表示无限 UserSessionQuota = 5 # 每个用户同时允许的会话数 SessionTimeout = "168h" # 会话过期时间 # ------------------- # 播放与转码 # ------------------- FFmpegPath = "/usr/local/bin/ffmpeg" # FFmpeg 可执行文件路径 Transcoding = true # 是否开启实时转码 MaxBitrate = 320 # 转码最大码率 kbps TranscodingCacheMaxSize = "1GB" # 转码缓存大小 AllowDownload = true # 是否允许客户端下载音乐 EnableCoverArt = true # 是否生成封面图 # ------------------- # API 设置 # ------------------- EnableSubsonic = true # 是否开启 Subsonic API SubsonicSalt = "随机字符串" # Subsonic API 密钥盐 EnableWebhooks = false # 是否开启 Webhooks 事件通知 EnableSpotify = false # 是否启用 Spotify 集成 SpotifyClientID = "" # Spotify Client ID SpotifyClientSecret = "" # Spotify Client Secret EnableLastFM = false # 是否集成 LastFM LastFMAPIKey = "" # LastFM API Key EnableListenBrainz = false # 是否集成 ListenBrainz ListenBrainzUsername = "" # ListenBrainz 用户名 ListenBrainzPassword = "" # ListenBrainz 密码 # ------------------- # 缓存设置 # ------------------- ImageCacheMaxSize = "1GB" # 封面图缓存大小 BackgroundCacheMaxSize = "1GB" # 背景缓存大小 编辑完成后，按键盘上的esc键退出编辑模式，然后输入:wq会出保存并退出 使用ls命令查看现有文件 刚刚我们的配置文件中写了数据库路径和音乐文件存放路径，我们需要创建对应的文件夹 使用mkdir命令创建data文件夹和music文件夹，然后使用ls名称查看是否创建对位置 mkdir ./data ./music 安装ffmpeg ffmpeg是开源多媒体处理工具，它主要用于音视频的 编码、解码、转码、录制和流式传输，我们在配置文件中写了启用编码，所以要安装这东西 有点linux源仓库里面有ffmpeg，有点没有，我们直接手动编译安装 说是手动，但是其实就是手动运行脚本 使用vi命令创建一个名称为install_ffmpeg.sh的文件 vi install_ffmpeg.sh 把下面内容复制粘贴进去，或者是直接到本站资源库里面搜索 #!/bin/bash # ============================================= # FFmpeg 静态编译安装/更新脚本 (AlmaLinux) # ============================================= set -e INSTALL_DIR="/usr/local/bin" TMP_DIR="/tmp/ffmpeg_install" FFMPEG_URL="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" echo "==> 准备临时目录..." rm -rf "$TMP_DIR" mkdir -p "$TMP_DIR" cd "$TMP_DIR" echo "==> 下载最新 FFmpeg..." wget -q --show-progress "$FFMPEG_URL" -O ffmpeg-static.tar.xz echo "==> 解压..." tar xJf ffmpeg-static.tar.xz cd ffmpeg-*-amd64-static echo "==> 安装/更新到 $INSTALL_DIR ..." sudo cp -f ffmpeg ffprobe "$INSTALL_DIR/" sudo chmod +x "$INSTALL_DIR/ffmpeg" "$INSTALL_DIR/ffprobe" echo "==> 清理临时文件..." rm -rf "$TMP_DIR" echo "==> 安装完成！版本信息：" ffmpeg -version echo "==> 如果重新运行脚本，将会更新到最新版本。" 按键盘上的ESC键退出编辑模式，输入:wq回车保存退出 使用chmod命令修改权限，让脚本可以运行 chmod +x install_ffmpeg.sh 运行脚本 ./install_ffmpeg.sh 测试启动 先测试一下是否可以正常启动，启动信息如果没有报错就是成功启动了 ./navidrome 设置开机自启动 进入/etc/systemd/system/文件夹下 cd /etc/systemd/system/ 使用vi命令创建一个名字为navidrome.service的文件 vi navidrome.service 把下面内容根据你的情况修改一下，主要是修改文件路径 [Unit] Description=navidrome daemon After=syslog.target network.target Wants=network.target [Service] Type=simple #启动文件路径 ExecStart=/opt/navidrome/navidrome Restart= always RestartSec=1min ExecStop=/usr/bin/killall navidrome [Install] WantedBy=multi-user.target 按键盘上的ESC退出编辑模式，输入:wq回车保存并退出 使用chmod命令给文件授权 chmod +x navidrome.service 让系统重新读取所有服务配置文件 systemctl daemon-reload 设置开机自启 systemctl enable navidrome 启动、停止、重启命令 启动命令 systemctl start navidrome 停止命令 systemctl stop navidrome 重启命令 systemctl restart navidrome 登录navidrome 使用浏览器，在地址栏输入IP:端口登录navidrome 第一次登录先要创建一个管理员账户 设置中文 点击右上角的用户图标 选择Personal 点击Language的下拉框，找到简体中文并选中 手机端 Navidrome 本身并没有官方手机客户端，但因为它兼容 Subsonic API，所以可以使用任何支持 Subsonic 的第三方音乐客户端。 软件推荐 Android 端推荐 1、Dsub（免费/开源） 支持离线缓存、流式播放、播放列表 支持 Subsonic API，兼容 Navidrome 下载方式： 前往项目地址下载或者本站资源库搜索下载 项目地址：https://github.com/paroj/DSub2000 2、Ultrasonic 界面简洁，支持流式播放和下载 支持多种音频格式 支持 Subsonic API 下载方式： 前往项目地址下载或者本站资源库搜索下载 项目地址：https://github.com/ultrasonic/ultrasonic 3、Subsonic 官方客户端 经典客户端，功能齐全 兼容 Navidrome 下载方式：闭源软件，本站不提供下载，自行百度 iOS 端推荐 1、Marvis Pro 高级音乐管理，支持 Subsonic 2、Subsonic iOS 官方 Subsonic 客户端，可用于 Navidrome 3、Dsub for iOS（部分第三方开发） 类似 Android 端 Dsub 下载方式：IOS端本站不提供下载 软件连接 这里使用安卓端的Dsub为例，其他软件也大同小异 打开软件，点击左上角的三条杠 点击设置 点击服务器 点击添加服务器 点击刚刚添加的服务器，进入编辑 输入服务器名称（随便填）然后服务器地址，用户名，密码，把测试连接上的允许不安全连接 填写完成后点击测试连接，连接成功即可