md_files/自学/linux服务器.md

1225 lines
36 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## llinux服务器以debian为例
### 预先准备
**域名购买与解析**
购买:[Low-Cost Domain Names & Hosting from $0.99 | NameSilo](https://www.namesilo.com/?rid=c562892jb)
教程:[【服务器、域名购买】Namesilo优惠码和域名解析教程附带服务器购买推荐和注意事项 | 爱玩实验室](https://iwanlab.com/namesilo/)
DNS解析可能需等待几分钟生效
![](https://pic.bitday.top/i/2025/03/19/u7b14x-2.png)
买的域名的r2studying.top 这里的HOSTNAME相当于二级域名如npm.r2studying.top
现改为CloudFlare来做DNS解析不用namesilo它有两种模式
**Proxied橙色云朵**:当你将某个 DNS 记录设置为 Proxied 时Cloudflare 会作为反向代理服务器处理该域名的 HTTP/HTTPS 流量。这样做有几个效果:
- **隐藏真实 IP**:用户访问时看到的是 Cloudflare 的 Anycast IP而不是你服务器的真实 IP从而提高安全性。
- **提供 CDN 加速**Cloudflare 会缓存静态资源,并通过全球节点加速内容传输,提升网站响应速度。
- **附加安全防护**:包括 DDoS 防护和 Web 应用防火墙等功能。
**DNS Only灰色云朵**:如果你设置为 DNS OnlyCloudflare 只负责 DNS 解析,不会对流量进行代理或处理。也就是说,用户访问时会直接获取并连接到你服务器的真实 IP。
**安全组设置**
登录云服务器的控制台设置
**入站规则**
入站规则Inbound Rules是指防火墙中用来控制外部流量进入服务器的规则。通过这些规则你可以指定允许或拒绝哪些类型的网络流量例如特定协议、端口号、IP地址等进入你的服务器。
| 类型 | 协议端口 | 源地址 | 描述 |
| ---- | ----------- | --------- | ------------------------------------------------------------ |
| IPv4 | TCP : 22 | 0.0.0.0/0 | 允许外部访问安全组内实例的SSH(22)端口用于远程登录Linux实例。 |
| IPv4 | TCP : 3389 | 0.0.0.0/0 | 允许外部访问安全组内实例的RDP(3389)端口用于远程登录Windows实例。 |
| IPv4 | TCP : 80 | 0.0.0.0/0 | 允许外部访问安全组内实例的HTTP(80)端口用于通过HTTP协议访问网站。 |
| IPv4 | TCP : 443 | 0.0.0.0/0 | 允许外部访问安全组内实例的HTTPS(443)端口用于通过HTTPS协议访问网站。 |
| IPv4 | TCP : 20-21 | 0.0.0.0/0 | 允许通过FTP上传和下载文件。 |
| IPv4 | ICMP: 全部 | 0.0.0.0/0 | 允许外部使用ping命令验证安全组内实例的网络连通性。 |
**出站规则**
出站规则Outbound Rules则是指控制服务器向外部发送流量的规则。你可以通过出站规则来限制服务器发出的数据包比如限制服务器访问某些外部服务或 IP 地址。
**凡是服务正常启动但是浏览器上无法访问的,都首先想想防火墙端口是否打开!!!**
### 常用的命令
- **cat** 用于查看文本文件的内容
- head 查看前n行
```text
head -n 100 文件名
```
- **touch** 新建文本文件如touch /home/hello.py 将在home 文件夹下新建hello.py
- **ls** 列出所有文件但默认只是显示出最基础的文件和文件夹如果需要更详细的信息则使用ls -la这将列出包括隐藏文件在内的所有文件和文件夹并且给出对应的权限、大小和日期等信息。
```text
zy123@hcss-ecs-588d:~$ ls -la
total 44
drwxr-xr-x 6 zy123 zy123 4096 Feb 26 08:53 .
drwxr-xr-x 3 root root 4096 Feb 24 16:33 ..
-rw------- 1 zy123 zy123 6317 Feb 25 19:41 .bash_history
-rw-r--r-- 1 zy123 zy123 220 Feb 24 16:33 .bash_logout
-rw-r--r-- 1 zy123 zy123 3526 Feb 24 16:33 .bashrc
drwx------ 3 zy123 zy123 4096 Feb 24 16:35 .config
drwxr-xr-x 3 zy123 zy123 4096 Feb 24 16:36 .local
-rw-r--r-- 1 zy123 zy123 807 Feb 24 16:33 .profile
drwxr-xr-x 5 zy123 zy123 4096 Feb 26 08:53 zbparse
drwxr-xr-x 3 root root 4096 Feb 26 08:54 zbparse_output
```
权限与文件类型(第一列):
- 第一个字符表示文件类型:
- “d”表示目录directory
- “-”表示普通文件regular file
- “l”表示符号链接symbolic link
- 后续的9个字符分为3组每组三个字符分别代表所有者、所属组和其他用户的权限读、写、执行
硬链接数(第二列):
表示指向该文件的硬链接数量。对于目录来说这个数字通常会大于1因为“.”和“..”也算在内。
所有者(第三列):
显示该文件或目录的拥有者用户名。
所属组(第四列):
显示该文件或目录所属的用户组。
文件大小(第五列):
以字节为单位显示文件的大小。对于目录通常显示的是目录文件占用的磁盘空间一般为4096字节
最后修改日期和时间(第六列):
显示文件最后一次修改的日期和时间(可能包含月、日和具体时间或年份)。
文件名或目录名(第七列):
显示文件或目录的名称。
- **cd** 进入指定文件夹如cd /home 将进入home目录。返回上层目录的命令是*cd ..*,返回刚才操作的目录的命令是*cd -*
- **mkdir** 新建文件夹如mkdir /home/Python 将在home 文件夹下新建一个Python 文件夹。
- **mv** 移动文件和文件夹,也可以用来修改名称,如:
```text
mv /home/hello.py /home/helloworld.py
```
将上文的hello.py重命名为helloworld.py
```text
mv /home/helloworld.py /home/Python/helloworld.py
```
将helloworld.py 由home文件夹移动到了次级的Python文件夹。
```text
mv /home/hello.py .
```
将/home/hello.py 移动到当前目录下
- **cp** 复制文件
```text
cp /home/Python/hellowrold.py /home/Python/HelloWorld.py
```
将helloworld.py复制为HelloWolrd.py。注意Linux系统严格区分大小写helloworld.py和HelloWolrd.py是两个文件。
- **rm** 删除即江湖传说中rm -rf r为递归可以删除文件夹中的文件f为强制删除。rm /home/Python/helloworld.py 可以删除刚才的helloworld.py 文件而想删除包括Python 在内的所有文件则是rm -rf /home/Python 。
- **du** -h 查看当前文件夹下各文件、文件夹的大小h是让文件自动使用K/M/G显示而不是只有K。“disk usage”磁盘使用情况
- **grep **是用于在文件或标准输入中搜索**符合条件的行**的命令。
```text
grep "pattern" filename #pattern可以是一个正则表达式
```
`-i`忽略大小写 `-n`显示行号
- **awk** 是一个功能强大的文本处理工具,它可以对文本文件进行分列处理、模式匹配和报告生成。它的语法类似一种简单的脚本语言。
```text
awk 'pattern { action }' filename
```
**pattern**:用于匹配文本的条件(可以省略,默认对所有行生效)。
**action**:在匹配的行上执行的操作。
`$0`:代表整行内容。
`$1, $2, ...`:代表各个字段(默认分隔符是空白字符,可以通过 `-F` 参数指定其他分隔符)。
```text
awk '{print $1, $3}' filename #印指定列
```
- 管道 `|` 是将一个命令的输出直接传递给另一个命令作为输入的一种机制。
示例:将 grep 与 awk 联合使用:假设有一个日志文件 `access.log`,需要先用 grep 过滤出包含 "ERROR" 的行,再用 awk 提取时间字段:
```access.log
127.0.0.1 27/Feb/2025:10:30:25 "GET /index.html HTTP/1.1" 200 1024
192.168.1.1 27/Feb/2025:10:31:45 "POST /login HTTP/1.1" 302 512
10.0.0.5 27/Feb/2025:10:32:10 "GET /error_page HTTP/1.1" 500 2048 ERROR
```
```text
grep 'ERROR' access.log | awk '{print $2}'
```
输出27/Feb/2025:10:32:10
- **lsof**"List Open Files"显示系统中当前打开的文件。 `-i`*会显示所有正在使用网络连接的进程*
```text
lsof -i :80 #查看 80 端口上的进程,或者判断80端口是否被占用
```
- **usermode** 修改用户账户信息的命令
```text
sudo usermod -aG docker zy123 #-aG一起用添加zy123到group组
```
- **chmod** 命令用于修改文件或目录的权限
1. 数字方式:数字方式使用三个(或四个)数字来表示所有者、组用户和其他用户的权限。每个数字代表读 (4)、写 (2)、执行 (1) 权限的和。
```text
chmod 644 filename
#所有者:读 + 写 = 6 组用户:读 = 4 其他用户:读 = 4
```
2. 符号方式
```text
chmod [用户类别][操作符][权限] filename
```
*用户类别:*
- `u`所有者user
- `g`组用户group
- `o`其他用户others
- `a`所有用户all等同于 `u+g+o`
*操作符:*
- `+`:增加权限
- `-`:去掉权限
- `=`:直接设置权限
*权限:*
- `r`:读权限
- `w`:写权限
- `x`:执行权限
```text
chmod u+x filename #为所有者增加执行权限
```
### 文本编辑器
**nano**Debian 11自带了简便易用的nano文本编辑器
```text
nano /etc/apt/sources.list #打开sources.list文件
```
![](https://pic.bitday.top/i/2025/03/19/u7ankb-2.png)
Ctrl+O:保存修改 ->弹出询问-> Y则保存N则不保存,ctrl+c 取消操作。
Ctrl+X:退出
**vim**
**普通模式Normal Mode**
打开 Vim 后默认进入普通模式。在该模式下,可以执行移动光标、删除、复制、粘贴等命令。
1. 光标移动:
`0`:跳到当前行行首
`$`:跳到当前行行尾
`gg`: 将光标移到文件开头
2. 文本操作:
**`dd`:删除(剪切)整行**
`yy`:复制(拷贝)整行
`p`:在光标后粘贴(把剪切或复制的内容贴上)
**`u`:撤销上一步操作**
`Ctrl + r`:重做上一步撤销的操作
**插入模式Insert Mode**
在普通模式下按 `i`、`I`、`a`、`A` 等键可进入插入模式,此时可以像普通编辑器那样输入文本。
按 `ESC` 键退出插入模式,返回普通模式。
**可视模式Visual Mode**
用于选中一段文本,自动进入可视模式。选中文本后可以进行复制、剪切等操作。
在可视模式下选中后按 `d` 删除
按 `y` 复制选中区域
**命令行模式Command-Line Mode**
在普通模式下,输入 `:` 进入命令行模式,可以执行保存、退出、查找等命令。
`:w`:保存当前文件
**`:q`:退出 Vim如果有未保存的修改会警告**
**`:wq` 或 `:x`:保存文件并退出**
`:q!`:不保存强制退出
`:set number`:显示行号
`:set paste`:适用于代码或格式敏感的文本,确保粘贴操作不会破坏原有的布局和缩进。
**`:%d`: 删除全文**
### 抓包
```text
sudo tcpdump -nn -i any port 1000 //查看请求端口1000的源 IP 地址
```
### SSH
生成密钥
```text
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```
默认会在当前用户的主目录下的 `~/.ssh/` 文件夹中生成两个文件:
- **私钥id_rsa**:必须保存在本地,切勿泄露或放到服务器上。它是用来证明你身份的重要凭证。
- **公钥id_rsa.pub**:需要复制到目标服务器上,通常放入服务器用户主目录下的 `~/.ssh/authorized_keys` 文件中,用于验证连接时与私钥匹配。
根据我的理解:
1.服务器从github上通过ssh拉取代码时需要把服务器的公钥放在github上因为拉代码时github需要认证服务器的身份就要用服务器给它提供的公钥加密。
2.通过windows上的finalshell连接linux服务器时需要在windows环境下生成一对密钥私钥用于ssh登录的时候输入公钥放在linux服务器的`~/.ssh/authorized_keys`文件中。因为ssh登录的时候服务器需要验证你的身份需要用你提供给它的公钥加密。
除此之外,还需要给文件和相关文件夹合适的权限:
```text
chmod 600 authorized_keys
chmod 700 ~/.ssh
```
### 文件系统
在 Linux 系统中,整个文件系统从根目录 `/` 开始,下面简单介绍一些主要目录及其存放的文件类型:
**/bin**
存放系统启动和运行时必需的用户二进制可执行文件,如常用的 shell 命令(例如 `ls`、`cp`、`mv` 等)。
**/boot**
包含启动加载器(如 GRUB的配置文件和内核映像kernel image这些文件用于系统启动过程。
**/dev**
包含设备文件这些文件代表系统中的各种硬件设备例如硬盘、终端、USB 设备等),以及一些伪设备。
**/etc**
存放系统范围内的配置文件,例如网络配置、用户账户信息、服务配置等。这些文件通常由管理员维护。
**/home**
为普通用户提供的家目录,每个用户在这里有一个独立的子目录,存放个人文件和配置。
**/lib 和 /lib64**
存放系统和应用程序所需的共享库文件,这些库支持 `/bin`、`/sbin` 及其他程序的运行。
**/media**
通常用于挂载移动介质如光盘、U 盘或其他可移动存储设备。
**/mnt**
提供一个临时挂载点,一般供系统管理员在需要手动挂载文件系统时使用。
**/opt**
用于安装附加的应用程序软件包,通常是第三方提供的独立软件,不与系统核心软件混合。
**/proc**
这是一个虚拟文件系统,提供内核和进程信息,例如系统资源使用情况、硬件信息、内核参数等。这里的文件不占用实际磁盘空间。
**/root**
系统管理员root 用户)的家目录,与普通用户的 `/home` 分开存放。
**/run**
存储系统启动后运行时产生的临时数据,比如 PID 文件、锁文件等,系统重启后会清空该目录。
**/sbin**
存放系统管理和维护所需的二进制文件(系统级命令),例如网络配置、磁盘管理工具等,这些通常只由 root 用户使用。
**/srv**
用于存放由系统提供的服务数据,如 FTP、HTTP 服务的数据目录等。
**/tmp**
用于存放临时文件,许多应用程序在运行时会将临时数据写入这里,系统重启后通常会清空该目录。
**/usr**
存放大量用户应用程序和共享资源,其子目录包括:
- **/usr/bin**:大部分用户命令和应用程序。
- **/usr/sbin**:非基本系统维护工具,主要供系统管理员使用。
- **/usr/lib**:程序库文件。
- **/usr/share**:共享数据,如文档、图标、配置样本等。
**/var**
存放经常变化的数据,如日志文件、缓存、邮件、打印队列和临时应用数据等。
### Bash
```text
#!/bin/bash
# 定义变量,注意等号两边不能有空格
name="World"
# 如果脚本传入了参数,则使用第一个参数覆盖默认值
if [ $# -ge 1 ]; then # $# 表示传入脚本的参数个数
name=$1 # $1 表示第一个参数。
fi
# 输出问候语
echo "Hello, $name!" #变量引用时要用 $ 符号,如 $name。
# 循环示例遍历1到5的数字
for i in {1..5}; do
echo "当前数字:$i"
done
# 定义一个函数函数名为greet
greet() {
echo "函数内问候: Hello, $1!"
}
# 调用函数并传入变量name作为参数
greet $name
```
**如何运行?**
赋予可执行权限
```text
chmod +x hello_world.sh
```
执行
```text
./hello_world.sh
或者
./hello_world.sh Alice #传参
```
在 Linux 系统中,默认情况下当前目录(`.`)并不包含在 PATH 环境变量中。这意味着,如果你在终端中直接输入脚本名(例如 `hello_world.sh`),系统不会在当前目录下查找这个脚本,而是只在 PATH 中指定的目录中查找可执行程序。使用 `./hello_world.sh` 表示“在当前目录下执行 hello_world.sh”从而告诉系统正确的路径。
**如何设置定时任务?**
```text
sudo crontab -e
#在里面添加:
10 0 * * * /path/toyour/xx.sh #让gpt写
```
## 反向代理神器——Nginx Proxy Manager
[【Docker系列】一个反向代理神器——Nginx Proxy Manager-我不是咕咕鸽](https://blog.laoda.de/archives/nginxproxymanager)
**概念**
**正向代理**是代理客户端的行为,即代理服务器代表客户端向目标服务器发出请求。客户端将自己的请求先发送给代理服务器,由代理服务器转发给真正的目标服务器,然后再将返回结果传递给客户端。
**特点:**
- **保护访问者(客户端)的信息**:目标服务器只会看到代理服务器的请求,无法直接获知真正发起请求的客户端是谁。
- **应用场景**当客户端出于隐私、访问控制或跨越网络限制的目的需要隐藏自己的真实IP或身份时会使用正向代理。
**反向代理**是代理服务器代表目标服务器接收客户端请求,并将请求转发给内部的真实服务器,然后将结果返回给客户端。客户端只与代理服务器通信,而不知道背后实际处理请求的服务器。
**特点:**
- **保护服务器端的信息**:客户端看不到真正的服务器细节,只知道代理服务器。这样可以隐藏真实服务器的 IP 和其他内部结构信息,从而增强安全性和负载均衡等功能。
- **应用场景**:在大型网站或应用中,为了防止恶意攻击或实现负载均衡,通常会在真实服务器前部署一个反向代理服务器。
**docker 部署**
```text
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80' # 保持默认即可不建议修改左侧的80
- '81:81' # 冒号左边可以改成自己服务器未被占用的端口
- '443:443' # 保持默认即可不建议修改左侧的443
volumes:
- ./data:/data # 冒号左边可以改路径,现在是表示把数据存放在在当前文件夹下的 data 文件夹中
- ./letsencrypt:/etc/letsencrypt # 冒号左边可以改路径,现在是表示把数据存放在在当前文件夹下的 letsencrypt 文件夹中
```
NPM后台管理网站运行在81号端口NPM服务本身监听80(http)和443(https)端口
**工作原理**
**用户访问网站80/443端口**
- 当用户访问 `https://blog.test.com` 时请求到达服务器的443端口。
- Nginx根据域名匹配代理规则由NPM配置将请求转发到后端服务如 `192.168.1.100:8080`)。
**管理员访问后台81端口**
- 管理员通过 `http://服务器IP:81` 访问NPM管理界面配置代理规则。
- 配置完成后NPM会自动生成Nginx配置文件并重启Nginx服务使新规则生效。
**两种方法实现SSL安全连接**
**1. 开启橙云+Cloudflare Origin CA**[网站SSL证书自动续期又又又失败了试试CloudFlare的免费证书15年有效期-我不是咕咕鸽](https://blog.laoda.de/archives/try-cloudflare-free-15-year-ssl-certificate)
- cloudflare解析DNS开启橙云
- Cloudflare Full (strict)模式(**灵活模式下无需以下步骤**)
- 在 Nginx Proxy ManagerNPM添加 Cloudflare Origin CA
- 配置 Proxy Host 使其使用
选择刚刚添加的 Cloudflare Origin CA 证书
选择 Force SSL强制 HTTPS
启用 HTTP/2 支持
Cloudflare Origin CA作用:实现cloudflare与源服务器之间的流量加密
**2.通配符SSL证书**[【Docker系列】反向代理神器NginxProxyManager——通配符SSL证书申请-我不是咕咕鸽](https://blog.laoda.de/archives/nginxproxymanager-ssl-wildcardcerts-for-your-entire-domain)
更推荐第二种目前正在使用但是3个月续签一次证书
**浏览器** → **(HTTPS)** → **NPM** → **(HTTP 或 HTTPS)** → **Gitea**
这就是反向代理常见的工作流程。
默认经常是 NPM 做 SSL 终止(内网用 HTTP 转发给 Gitea。如果你想内外全程加密就要让 NPM -> Gitea 这段也走 HTTPS并在 Gitea 上正确配置证书。
## 正向代理(用于拉取镜像)
下载Clash客户端[Release Clash-Premium · DustinWin/proxy-tools](https://github.com/DustinWin/proxy-tools/releases/tag/Clash-Premium)
或者[Index of /Linux/centOS/](https://app.chongjin01.icu/Linux/centOS/)
我是windows上下载clashpremium-release-linux-amd64.tar.gz 然后FTP上传到linux服务器上。
下载配置文件config.yaml每个人独一无二的
wget -O /home/zy123/VPN/config.yaml "https://illo1.no-mad-world.club/link/2zXAEzExPjAi6xij?clash=3"
类似这样:
```text
port: 7890
socks-port: 7891
allow-lan: false
mode: Rule //Global
log-level: info
external-controller: 0.0.0.0:9090
unified-delay: true
hosts:
time.facebook.com: 17.253.84.125
time.android.com: 17.253.84.125
dns:
enable: true
use-hosts: true
nameserver:
- 119.29.29.29
- 223.5.5.5
- 223.6.6.6
- tcp://223.5.5.5
- tcp://223.6.6.6
- tls://dns.google:853
- tls://8.8.8.8:853
- tls://8.8.4.4:853
- tls://dns.alidns.com
- tls://223.5.5.5
- tls://223.6.6.6
- tls://dot.pub
- tls://1.12.12.12
- tls://120.53.53.53
- https://dns.google/dns-query
- https://8.8.8.8/dns-query
- https://8.8.4.4/dns-query
- https://dns.alidns.com/dns-query
- https://223.5.5.5/dns-query
- https://223.6.6.6/dns-query
- https://doh.pub/dns-query
- https://1.12.12.12/dns-query
- https://120.53.53.53/dns-query
default-nameserver:
- 119.29.29.29
- 223.5.5.5
- 223.6.6.6
- tcp://119.29.29.29
- tcp://223.5.5.5
- tcp://223.6.6.6
proxies:
- {name: 🇭🇰 香港Y01, server: qvhh1-g03.hk01-ae5.entry.v50307shvkaa.art, port: 19273, type: ss, cipher: aes-256-gcm, password: 6e4124c4-456e-36a3-b144-c0e1a618d04c, udp: true}
```
注意魔戒vpn给的是一个订阅地址还需要解码
简便方法windows上将订阅链接导入自动解析成yaml配置文件然后直接把该文件传到服务器上
![image-20250309173756312](https://pic.bitday.top/i/2025/03/19/u79q0t-2.png)
**启动Clash**
```text
./CrashCore -d . & //后台启动
```
**为Clash创建服务**
1.创建 `systemd` 服务文件
```text
sudo vim /etc/systemd/system/clash.service
```
2.在文件中添加以下内容:
```text
[Unit]
Description=Clash Proxy Service
After=network.target
[Service]
ExecStart=/home/zy123/VPN/CrashCore -d /home/zy123/VPN
WorkingDirectory=/home/zy123/VPN
Restart=always
User=zy123
Group=zy123
[Install]
WantedBy=multi-user.target
```
这段配置将 Clash 配置为:
- 在网络服务启动后运行。
- 在启动时自动进入后台,执行 `CrashCore` 服务。
- 如果服务意外停止,它将自动重启。
- 以 `zy123` 用户身份运行 Clash。
启动服务:
```text
sudo systemctl start clash
```
停止服务:
```text
sudo systemctl stop clash
```
查看服务状态:
```text
sudo systemctl status clash
```
**配置YACD**
YACD 是一个基于 **Clash** 的 Web 管理面板,用于管理您的 Clash 配置、查看流量和节点信息等。
**直接用现成的**https://yacd.haishan.me/
**服务器上部署**目前是npm手动构建安装启动的。
下载yacd
```text
git clone https://github.com/haishanh/yacd.git
```
安装npm
构建yacd
```text
cd ~/VPN/yacd
pnpm install
pnpm build
```
启动yacd
```text
nohup pnpm serve --host 0.0.0.0 & //如果不是0.0.0.0 不能在windows上打开
```
**停止进程**
```text
ps aux | grep pnpm
kill xxx
```
通过http://124.71.159.195:4173/ 访问yacd控制面板。手动添加crash服务所在的ip:端口。
如果连不上yacd和crash都是http协议就行了。
使用代理curl -x http://127.0.0.1:7890 https://www.google.com
## File Browser 文件分享
https://github.com/filebrowser/filebrowser
[Docker 部署 File Browser 文件管理系统_filebrowser docker-CSDN博客](https://blog.csdn.net/qq_41906909/article/details/144726676)
1.创建数据目录
```text
mkdir -p /data/filebrowser/{srv,config,db}
```
2.目录授权
```text
chmod -R 777 /data/filebrowser/
```
3.编辑 docker-compose.yaml 文件
```text
version: '3'
services:
filebrowser:
image: filebrowser/filebrowser:s6
container_name: filebrowser
restart: always
ports:
- "2000:80" # 将容器的80端口映射到宿主机2000端口
volumes:
- /data/filebrowser/srv:/srv #保存用户上传的文件
- /data/filebrowser/config:/config # 配置文件存储路径
- /data/filebrowser/db:/database #数据库存储路径
```
### 调用API实现文件上传与下载
**登录:**
```text
# 登录 → 获取 JWT token原始字符串
curl -X POST "yourdomain/api/login" \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "123456"
}'
响应: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" //jwt令牌
```
**上传:**
```text
# 先把 token 保存到环境变量(假设你已经执行过 /api/login 并拿到了 JWT
export TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"
# 定义要上传的本地文件和目标名称
FILE_PATH="/path/to/local/photo.jpg"
OBJECT_NAME="photo.jpg"
# 对远程路径做 URL 编码(保留斜杠)
REMOTE_PATH="store/${OBJECT_NAME}"
ENCODED_PATH=$(printf "%s" "${REMOTE_PATH}" \
| jq -sRr @uri \
| sed 's/%2F/\//g')
# 发起上传请求raw body 模式)
curl -v -X POST "https://yourdomain/api/resources/${ENCODED_PATH}?override=true" \
-H "X-Auth: ${TOKEN}" \
-H "Content-Type: image/jpeg" \ # 根据文件后缀改成 image/png 等
--data-binary "@${FILE_PATH}"
```
**拼接下载url**
```text
String downloaded_url=yourdomain + "/api/raw/" + ${ENCODED_PATH};
```
## Gitea
[Gitea Docker 安装与使用详解:轻量级自托管 Git 服务教程-CSDN博客](https://blog.csdn.net/m0_70878103/article/details/144908188)
```text
version: "3"
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
ports:
- "3000:3000" # 将宿主机的3000端口映射到容器的3000端口
volumes:
- /data/gitea:/data # 持久化存储Gitea数据包括仓库、配置、日志等
```
## EasyImage
[【好玩儿的Docker项目】10分钟搭建一个简单图床——Easyimage-我不是咕咕鸽](https://blog.laoda.de/archives/docker-compose-install-easyimage)
github地址[icret/EasyImages2.0: 简单图床 - 一款功能强大无数据库的图床 2.0版](https://github.com/icret/EasyImages2.0)
```text
sudo -i # 切换到root用户
apt update -y # 升级packages
apt install wget curl sudo vim git # Debian系统比较干净安装常用的软件
```
```text
version: '3.3'
services:
easyimage:
image: ddsderek/easyimage:latest
container_name: easyimage
ports:
- '1000:80'
environment:
- TZ=Asia/Shanghai
- PUID=1000
- PGID=1000
volumes:
- '/root/data/docker_data/easyimage/config:/app/web/config'
- '/root/data/docker_data/easyimage/i:/app/web/i'
restart: unless-stopped
```
网页打开显示bug
```text
cd /data/easyimage/config/config.php
```
![image-20250315101454031](https://pic.bitday.top/i/2025/03/19/u7apqr-2.png)
这里添加上https
网站域名 图片域名设置可以改变图片的urlIP或域名
![image-20250306183642549](https://pic.bitday.top/i/2025/03/19/u7a1lv-2.png)
**picgo安装**
[Releases · Molunerfinn/PicGo](https://github.com/Molunerfinn/PicGo/releases)
1.右下角小窗打开
2.插件设置搜索web-uploader 1.1.1 自定义web图床
旧版有搜索不出来的情况!建议直接安装最新版!
3.配置如下API地址从easyimage-设置-API设置中获取![image-20250306141151376](https://pic.bitday.top/i/2025/03/19/u79xiv-2.png)
**typora设置**
左上角文件-偏好设置-图像-插入图片时{
**上传图片**-picgo服务器-填写picgo安装路径
}
ps:还可以选择上传到./assets每个md文件独立
或者上传到指定路径如/image多个md文件共享
py脚本1将所有md文件中的图片路径改为本地统一保存到**本地**output文件夹中
py脚本2将每个md文件及其所需图片单独保存保存到**本地**但每个md文件有自己独立的assets文件夹
py脚本3将本地图片上传到easyimage图床并将链接返回替换md文件中的本地路径
## Typecho
[【好玩儿的Docker项目】10分钟搭建一个Typecho博客太破口念念不忘必有回响-我不是咕咕鸽](https://blog.laoda.de/archives/docker-compose-install-typecho)
typecho:https://github.com/typecho/typecho/
注意nginx一定要对typecho目录有操作权限
```text
sudo chmod 755 -R ./typecho
```
```text
services:
nginx:
image: nginx
ports:
- "4000:80" # 左边可以改成任意没使用的端口
restart: always
environment:
- TZ=Asia/Shanghai
volumes:
- ./typecho:/var/www/html
- ./nginx:/etc/nginx/conf.d
- ./logs:/var/log/nginx
depends_on:
- php
networks:
- web
php:
build: php
restart: always
expose:
- "9000" # 不暴露公网故没有写9000:9000
volumes:
- ./typecho:/var/www/html
environment:
- TZ=Asia/Shanghai
depends_on:
- mysql
networks:
- web
pyapp:
build: ./markdown_operation # Dockerfile所在的目录
restart: "no"
networks:
- web
env_file:
- .env
depends_on:
- mysql
mysql:
image: mysql:5.7
restart: always
environment:
- TZ=Asia/Shanghai
expose:
- "3306" # 不暴露公网故没有写3306:3306
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/logs:/var/log/mysql
- ./mysql/conf:/etc/mysql/conf.d
env_file:
- mysql.env
networks:
- web
networks:
web:
```
卸载:
```text
sudo -i # 切换到root
cd /root/data/docker_data/typecho # 进入docker-compose所在的文件夹
docker-compose down # 停止容器,此时不会删除映射到本地的数据
cd ~
rm -rf /root/data/docker_data/typecho # 完全删除映射到本地的数据
```
### 主题
Joe主题https://github.com/HaoOuBa/Joe
[Joe再续前缘主题 - 搭建本站同款网站 - 易航博客](https://blog.yihang.info/archives/18.html)
自定义文章详情页的上方信息(如更新日期/文章字数第):
`/typecho/usr/themes/Joe/functions.php`中定义art_count统计字数(粗略)。
```text
原始 Markdown →
[1] 删除代码块/行内代码/图片/链接标记/标题列表标记/强调符号 →
[2] strip_tags() + html_entity_decode() →
[3] 正则保留 “文字+数字+标点”,去除其它 →
结果用 mb_strlen() 得到最终字数
```
`typecho/usr/themes/Joe/module/single/batten.php`
```php
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) {
http_response_code(404);
exit;
}
?>
<h1 class="joe_detail__title"><?php $this->title() ?></h1>
<div class="joe_detail__count">
<div class="joe_detail__count-information">
<a href="<?php $this->author->permalink(); ?>">
<img width="38" height="38" class="avatar lazyload" src="<?php joe\getAvatarLazyload(); ?>" data-src="<?php joe\getAvatarByMail($this->author->mail) ?>" alt="<?php $this->author(); ?>" />
</a>
<div class="meta ml10">
<div class="author">
<a class="link" href="<?php $this->author->permalink(); ?>" title="<?php $this->author(); ?>"><?php $this->author(); ?></a>
</div>
<div class="item">
<span class="text">
<?php echo $this->date('Y-m-d'); ?> /&nbsp;
<?php $this->commentsNum('%d'); ?> 评论 /&nbsp;
<?php echo joe\getAgree($this); ?> 点赞 /&nbsp;
<?php echo joe\getViews($this); ?> 阅读 /&nbsp;
<?php echo art_count($this->cid); ?> 字
</span>
</div>
</div>
</div>
</div>
<div class="relative" style="padding-right: 40px;">
<i class="line-form-line"></i>
<!-- 新增最近修改日期显示 -->
<div style="font-size: 1.0em; position: absolute; right: 20px; top: 50%; transform: translateY(-50%);">
最后更新于 <?php echo date('m-d', $this->modified); ?>
</div>
<div class="flex ac single-metabox abs-right">
<div class="post-metas">
<!-- 原图标及其他冗余信息已删除 -->
</div>
<div class="clearfix ml6">
<!-- 编辑文章/页面链接已删除 -->
</div>
</div>
</div>
```
修改代码块背景色:
`typecho/usr/themes/Joe/assets/css/joe.global.css`
```css
.joe_detail__article code:not([class]) {
border-radius: var(--radius-inner, 4px); /* 可以设置一个默认值 */
background: #f5f5f5; /* 稍微偏灰的背景色 */
color: #000000; /* 黑色字体 */
padding: 2px 6px; /* 内边距可以适当增大 */
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
word-break: break-word;
font-weight: normal;
-webkit-text-size-adjust: 100%;
-webkit-font-smoothing: antialiased;
white-space: pre-wrap; /* 保持代码换行 */
font-size: 0.875em;
margin-inline-start: 0.25em;
margin-inline-end: 0.25em;
}
```
大坑:{x}会显示为勾选框无法正常进行latex公式解析因为`typecho/usr/themes/Joe/public/short.php`中设置了短代码替换,**在文章输出前**对 `$content` 中的特定标记或短代码进行搜索和替换,从而实现一系列自定义功能。现已全部注释。
`typecho/usr/themes/Joe/assets/js/joe.single.js`原版: 显示弹窗,点叉后消失
```text
{
document.querySelector('.joe_detail__article').addEventListener('copy', () => {
autolog.log(`本文版权属于 ${Joe.options.title} 转载请标明出处!`, 'warn', false);
});
}
```
显示5秒后消失
```text
document.querySelector('.joe_detail__article').addEventListener('copy', () => {
// 显示 autolog 消息
autolog.log(`本文版权属于 ${Joe.options.title} 转载请标明出处!`, 'warn', false);
// 5 秒后删除该消息
setTimeout(() => {
const warnElem = document.querySelector('.autolog-warn');
if (warnElem) {
warnElem.remove(); // 或者使用 warnElem.style.display = 'none';
}
}, 5000);
});
```
### **markdown编辑与解析**
确保代码块\```后面紧跟着语言,如\```java否则无法正确显示。
markdown编辑器插件https://xiamp.net/archives/aaeditor-is-another-typecho-editor-plugin.html
- '开启公式解析!'
markdown解析器插件[mrgeneralgoo/typecho-markdown: A markdown parse plugin for typecho.](https://github.com/mrgeneralgoo/typecho-markdown)
- 关闭公式解析,仅开启代码解析!
slug为页面缩略名在新增文章时可以传入默认是index数字。
![image-20250320185818633](https://pic.bitday.top/i/2025/03/20/uqbaps-0.png)
## qBittorrent
[【好玩的Docker项目】10分钟搭建你专属的下载神器——qbittorrent-我不是咕咕鸽](https://blog.laoda.de/archives/docker-install-qbittorrent)
```text
docker pull linuxserver/qbittorrent
```
```text
cd ~
mkdir /root/data/docker_data/qBittorrent #创建qbitorrent数据文件夹
cd /root/data/docker_data/qBittorrent
mkdir config downloads #创建配置文件目录与下载目录
nano docker-compose.yml #创建并编辑文件
```
```text
services:
qbittorrent:
image: linuxserver/qbittorrent
container_name: qbittorrent
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai # 你的时区
- UMASK_SET=022
- WEBUI_PORT=8081 # 将此处修改成你欲使用的 WEB 管理平台端口
volumes:
- ./config:/config # 绝对路径请修改为自己的config文件夹
- ./downloads:/downloads # 绝对路径请修改为自己的downloads文件夹
ports:
# 要使用的映射下载端口与内部下载端口,可保持默认,安装完成后在管理页面仍然可以改成其他端口。
- 6881:6881
- 6881:6881/udp
# 此处WEB UI 目标端口与内部端口务必保证相同见问题1
- 8081:8081
restart: unless-stopped
```