随机图片API部署

Github 准备 1 2 #安装所需程序 sudo apt install nginx php7.4-fpm php7.4-mysql php7.4-fpm php7.4-mysql php7.4-cli php7.4-opcache certbot python3-certbot-nginx python3-certbot-dns-cloudflare 创建Index.php文件 这里只需要修改路径 主路径 1 2 cd /var/www/html nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <?php $pcPath = '/landscape';#这里的路径自行修改 $mobilePath = '/portrait';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 检测用户代理以区分手机和电脑访问 $userAgent = $_SERVER['HTTP_USER_AGENT']; $isMobile = preg_match('/(android|iphone|ipad|ipod|blackberry|windows phone)/i', $userAgent); // 根据访问设备设置图片路径 if ($isMobile) { $path = $mobilePath; } else { $path = $pcPath; } // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> PC路径 1 2 mkdir /var/www/html/pc && cd /var/www/html/pc nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <?php $pcPath = '../landscape';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 设置图片路径为 landscape $path = $pcPath; // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> Mobile路径 1 2 mkdir /var/www/html/mobile && cd /var/www/html/mobile nano index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 <?php $pcPath = '../portrait';#这里的路径自行修改 // 函数:从目录中获取图片列表 function getImagesFromDir($path) { $images = array(); if ($img_dir = @opendir($path)) { while (false !== ($img_file = readdir($img_dir))) { // 匹配 webp、jpg、jpeg、png、gif 格式的图片 if (preg_match("/\.(webp|jpg|jpeg|png|gif)$/i", $img_file)) { $images[] = $img_file; } } closedir($img_dir); } return $images; } // 函数:生成完整的图片路径 function generateImagePath($path, $img) { return $path . '/' . $img; } // 设置图片路径为 portrait $path = $pcPath; // 缓存图片列表 $imgList = getImagesFromDir($path); // 从列表中随机选择一张图片 shuffle($imgList); $img = reset($imgList); // 获取图片的格式 $img_extension = pathinfo($img, PATHINFO_EXTENSION); // 根据图片的格式设置 Content-Type switch ($img_extension) { case 'webp': header('Content-Type: image/webp'); break; case 'jpg': case 'jpeg': header('Content-Type: image/jpeg'); break; case 'png': header('Content-Type: image/png'); break; case 'gif': header('Content-Type: image/gif'); break; // 添加其他格式的处理方式 // case 'bmp': // header('Content-Type: image/bmp'); // break; } // 生成完整的图片路径 $img_path = generateImagePath($path, $img); // 直接输出所选的随机图片 readfile($img_path); ?> 反代开启HTTPS 1 2 3 4 #清空默认配置 > /etc/nginx/sites-available/default #手动编辑默认配置 sudo nano /etc/nginx/sites-available/default 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 server { listen [::]:8080; listen 8080; server_name example.com; # 替换为你的域名以便下面申请域名 root /var/www/html; # 设置网站根目录 # 默认首页是 index.php 或其他文件(根据你的需求) index index.php index.html index.htm; # 处理根目录请求,直接返回根目录下的文件(如果存在) location / { try_files $uri $uri/ /index.php?$query_string; } # 处理 PHP 文件 location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 防止访问 .ht 文件(如果有) location ~ /\.ht { deny all; } } 1 2 3 4 #测试Nginx配置 sudo nginx -t #重新加载Nginx配置 sudo systemctl reload nginx 现在可以访问ip:8080查看效果 ...

五月 15, 2025 · 5 分钟 · 2278 字 · Beiyuan · 

Linux修改DNS

方法一:Systemd-resolved 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #查看是否安装 sudo systemctl status systemd-resolved #没有安装执行命令安装并启动 sudo apt update sudo apt install systemd-resolved -y sudo systemctl enable systemd-resolved && sudo systemctl start systemd-resolved #修改DNS sudo nano /etc/systemd/resolved.conf #示例 [Resolve] DNS=8.8.8.8 1.1.1.1 FallbackDNS=8.8.4.4 #修改完后退出,重新启动 sudo systemctl restart systemd-resolved 1 2 3 4 5 6 7 8 9 10 11 12 13 #报错masked输入下面的命令 sudo systemctl unmask systemd-resolved #再次重启 sudo systemctl restart systemd-resolved #查看是否修改成功 resolvectl status #查看是否软链接成功 ls -l /etc/resolv.conf #上面命令示例 lrwxrwxrwx 1 root root 32 Feb 11 2024 /etc/resolv.conf -> /run/systemd/resolve/resolv.conf #不一样执行下面的命令后再次查看 sudo rm /etc/resolv.conf sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf 方法二:Resolved 1 2 3 4 5 sudo apt update sudo apt install resolvconf sudo nano /etc/resolv.conf #防止被修改 sudo chattr +i /etc/resolv.conf

五月 15, 2025 · 1 分钟 · 253 字 · Beiyuan · 

Linux创建python虚拟环境解决依赖问题

1 sudo apt update && sudo apt install python3 -y #安装python 1 2 3 4 5 sudo apt install python3-venv -y #安装虚拟环境 mkdir /opt/env && cd /opt/env #创建文件夹单独存放相关文件和配置,也可以不创建 python3 -m venv env #创建虚拟环境,env是你虚拟环境的名称,可以自定义,这里创建虚拟环境同时会创建一个文件夹 source env/bin/activate #激活虚拟环境,这里的env同理,需要和上面一致 deactivate #关闭虚拟环境

五月 15, 2025 · 1 分钟 · 148 字 · Beiyuan · 

Hugo主题Papermod设置文章内基本链接在新标签页打开

(1)在 assets/css/common/post-single.css 添加样式代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 .post-content a code { margin: auto 0; border-radius: 0; box-shadow: 0 -1px 0 var(--primary) inset; } .post-content a.external-link { display: inline-flex; align-items: center; gap: 5px; } .post-content a.external-link::after { content: ""; display: inline-block; clip-path: polygon(60% 5%, 60% 0%, 100% 0%, 100% 5%, 100% 40%, 94.98% 40%, 94.98% 5%, 94.98% 9.59%, 42.41% 59.2%, 38.1% 54.64%, 90.7% 5%, 60% 5%, 50% 8%, 13% 8%, 8% 8%, 8% 92%, 92% 92%, 92% 50%, 87% 50%, 87% 87%, 13% 87%, 13% 13%, 50% 13%, 50% 8%); background-color: var(--primary); width: 18px; height: 18px; } .post-content del { text-decoration: line-through; } (2)在theme的 layouts/_default/_markup/render-link.html 添加代码 如果没有 render-link.html 文件的话,直接新建,再将代码拷贝进去 ...

五月 15, 2025 · 1 分钟 · 272 字 · Beiyuan · 

Docker部署WebSSH-Nexus Terminal

GIthub 1 mkdir /opt/ssh && cd /opt/ssh 1 2 3 4 5 #下载docker-compose.yml及.env wget https://raw.githubusercontent.com/Heavrnl/nexus-terminal/refs/heads/main/docker-compose.yml -O docker-compose.yml && wget https://raw.githubusercontent.com/Heavrnl/nexus-terminal/refs/heads/main/.env -O .env #编辑,按需修改 nano docker-compose.yml nano .env Docker开启ipv6 在 /etc/docker/daemon.json 加入以下内容,不存在就直接创建 修改完后重启docker sudo systemctl restart docker 1 2 3 4 5 6 { "ipv6": true, "fixed-cidr-v6": "fd00::/80", "ip6tables": true, "experimental": true } 1 2 #启动 docker compose up -d Nginx反代 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #安装所需程序 sudo apt install certbot python3-certbot-nginx python3-certbot-dns-cloudflare nginx #清空默认配置 > /etc/nginx/sites-available/default #手动编辑一个名为ssh的配置 sudo nano /etc/nginx/sites-available/ssh #启用配置 sudo ln -s /etc/nginx/sites-available/ssh /etc/nginx/sites-enabled/ #从Cloudflare获取区域DNS API,这里如果你需要使用CF申请证书也不想关小黄云再操作 sudo nano /etc/letsencrypt/cloudflare.ini dns_cloudflare_api_token = 你的API #赋予权限 sudo chmod 600 /etc/letsencrypt/cloudflare.ini #使用CF-DNS申请证书,全程y就行 sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d example.com #替换为你的域名 #直接申请证书,上面的申请完后可以用这个命令自动配置HTTPS,选1 sudo certbot --nginx -d example.com #替换为你的域名 配置示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 server { listen 80; # 端口可以随意修改 listen [::]:80; # 支持 IPv6,端口同样可以修改 server_name example.com; # 你的域名 location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Range $http_range; proxy_set_header If-Range $http_if_range; proxy_redirect off; proxy_pass http://127.0.0.1:18111; } } 1 2 sudo nginx -t #检查配置 sudo systemctl reload nginx #重新加载配置 完成后访问你的域名即可 ...

五月 15, 2025 · 1 分钟 · 500 字 · Beiyuan · 

Docker部署watchtower自动更新Docker容器

GitHub 原文 Docker 1 2 3 4 docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower 自动清除旧镜像 官方给出的默认启动命令在长期使用后会堆积非常多的标签为 none 的旧镜像,如果放任不管会占用大量的磁盘空间。要避免这种情况可以加入 --cleanup 选项,这样每次更新都会把旧的镜像清理掉。 --cleanup 选项可以简写为 -c: 1 2 3 4 5 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -c 选择性自动更新 容器更新列表 假设我们只想更新 nginx、redis 这两个容器,我们可以把容器名称追加到启动命令的最后面,就像下面这个例子: 1 2 3 4 5 6 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -c \ nginx redis 博主觉得把需要更新的容器名称写在启动命令中不利于管理,于是想了个更好的方法,建立一个更新列表文件。 1 2 3 4 5 cat ~/.watchtower.list aria2-pro unlockmusic mtg ... 通过变量的方式去调用这个列表: 1 2 3 4 5 6 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -c \ $(cat ~/.watchtower.list) 这样只需要调整列表后删除 Watch­tower 容器并重新执行上面的命令重新启动 Watch­tower 即可。 设置单个容器自动更新特征 给容器中添加 com.centurylinklabs.watchtower.enable 这个 LA­BEL 并设置它的值为 false,或者在启动命令中加入 --label com.centurylinklabs.watchtower.enable=false 参数可以排除相应的容器。下面这个例子是博主的 openwrt-mini 镜像的容器启动命令,Watch­tower 将永远忽略它的更新,即使它包含在自动更新列表中。 1 2 3 4 5 6 7 8 docker run -d \ --name openwrt-mini \ --restart always \ --network openwrt \ --privileged \ --label com.centurylinklabs.watchtower.enable=false \ p3terx/openwrt-mini \ /sbin/init 当容器启动命令中加入 --label com.centurylinklabs.watchtower.enable=true 参数,并且给 Watch­tower 加上 --label-enable 选项时,Watch­tower 将只更新这些包含此参数的容器。 --label-enable 可以简写为 -e: 1 2 3 4 5 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -ce 因为需要在容器启动时进行设置,且设置后就无法直接更改,只能重建容器,所以这种方式的灵活性不如更新列表法。尤其是在设置 com.centurylinklabs.watchtower.enable=false 参数后容器将永远被 Watch­tower 忽略,也包括后面将要提到的手动更新方式,所以一般不推荐这样做,除非你愿意手动重建的原生方式更新。 设置自动更新检查频率 --interval, -i - 设置更新检测时间间隔,单位为秒。比如每隔 1 个小时检查一次更新 1 2 3 4 5 6 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -c \ --interval 3600 --schedule, -s - 设置定时检测更新时间。格式为 6 字段 Cron 表达式,而非传统的 5 字段,即第一位是秒。比如每天凌晨 2 点检查一次更新: 1 2 3 4 5 6 docker run -d \ --name watchtower \ --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -c \ --schedule "0 0 2 * * *" 手动更新 前面的使用方式都是让 Watch­tower 以 detached(后台)模式在运行并自动更新容器,而 Watch­tower 也支持以 foreground(前台)模式来使用,即运行一次退出并删掉容器,来实现手动更新容器。这对于偶尔更新一次那些不在自动更新列表中的容器非常有用。 对于 foreground 模式,需要加上 --run-once 这个专用的选项。下面的例子 Docker 会运行一次 Watch­tower 并检查 aria2-pro 容器的基础镜像更新,最后删掉本次运行创建的 Watch­tower 容器。 --run-once 可以简写为 -R: 1 2 3 4 docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower -cR \ aria2-pro 需要注意的是当这个容器设置过 com.centurylinklabs.watchtower.enable=false 参数时不会更新。

五月 15, 2025 · 3 分钟 · 1167 字 · Beiyuan · 

Docker部署Sub-store订阅管理

Docker Github 1 mkdir /opt/sub-store && cd /opt/sub-store 1 2 3 4 5 6 7 docker run -it -d --restart=always \ -e "SUB_STORE_BACKEND_SYNC_CRON=55 23 * * *" \ -e "SUB_STORE_FRONTEND_BACKEND_PATH=/G5uT9nqA7rXyJ2zV8LwP" \ -p 3001:3001 \ -v /opt/sub-store:/opt/app/data \ --name sub-store \ xream/sub-store

五月 15, 2025 · 1 分钟 · 41 字 · Beiyuan · 

Docker部署Sublinkx订阅管理

Github 1 2 3 4 5 6 docker run -d --name sublinkx \ -p 7999:8000 \ -v ./db:/app/db \ -v ./template:/app/template \ -v ./logs:/app/logs \ jaaksi/sublinkx

五月 15, 2025 · 1 分钟 · 26 字 · Beiyuan · 

Docker部署netdata监控系统数据

Github 1 2 3 # 创建文件夹及yaml文件 mkdir -p /opt/netdata/netdataconfig /opt/netdata/netdatalib /opt/netdata/netdatacache && cd /opt/netdata nano docker-compose.yaml Docker-compose 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 services: netdata: image: netdata/netdata container_name: netdata pid: host network_mode: "host" restart: unless-stopped cap_add: - SYS_PTRACE - SYS_ADMIN security_opt: - apparmor:unconfined ports: - "19999:19999" volumes: - ./netdataconfig:/etc/netdata - ./netdatalib:/var/lib/netdata - ./netdatacache:/var/cache/netdata - /:/host/root:ro,rslave - /etc/passwd:/host/etc/passwd:ro - /etc/group:/host/etc/group:ro - /etc/localtime:/etc/localtime:ro - /proc:/host/proc:ro - /sys:/host/sys:ro - /etc/os-release:/host/etc/os-release:ro - /var/log:/host/var/log:ro - /var/run/docker.sock:/var/run/docker.sock:ro volumes: netdataconfig: netdatalib: netdatacache: 1 docker compose up -d Docker CLI 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 docker run -d --name=netdata \ --pid=host \ --network=host \ -p 19999:19999 \ -v ./netdataconfig:/etc/netdata \ -v ./netdatalib:/var/lib/netdata \ -v ./netdatacache:/var/cache/netdata \ -v /:/host/root:ro,rslave \ -v /etc/passwd:/host/etc/passwd:ro \ -v /etc/group:/host/etc/group:ro \ -v /etc/localtime:/etc/localtime:ro \ -v /proc:/host/proc:ro \ -v /sys:/host/sys:ro \ -v /etc/os-release:/host/etc/os-release:ro \ -v /var/log:/host/var/log:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ --restart unless-stopped \ --cap-add SYS_PTRACE \ --cap-add SYS_ADMIN \ --security-opt apparmor=unconfined \ netdata/netdata 1 sudo cat /opt/netdata/netdatalib/netdata_random_session_id

五月 15, 2025 · 1 分钟 · 205 字 · Beiyuan · 

Docker部署Memos个人备忘录

Github 1 2 3 # 创建文件夹及yaml文件 mkdir /opt/memos && cd /opt/memos nano docker-compose.yaml Docker-CLI 1 2 3 4 5 6 docker run -d \ --init \ --name memos \ --publish 5230:5230 \ --volume ~/.memos/:/var/opt/memos \ neosmemo/memos:stable 更新 1 2 3 4 5 6 docker run -d \ --init \ --name memos \ --publish 5230:5230 \ --volume ~/.memos/:/var/opt/memos \ neosmemo/memos:0.23.0-rc Docker-compose 1 2 3 4 5 6 7 8 services: memos: image: neosmemo/memos:stable container_name: memos volumes: - ~/.memos/:/var/opt/memos ports: - 5230:5230 更新 1 2 3 4 docker stop memos && docker rm memos cp -r ~/.memos/memos_prod.db ~/.memos/memos_prod.db.bak docker pull neosmemo/memos:0.23.0-rc.0 docker pull neosmemo/memos:stable 使用外部数据库 Postgres数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 services: memos: image: neosmemo/memos:stable restart: always depends_on: - db ports: - "5230:5230" environment: MEMOS_DRIVER: postgres MEMOS_DSN: "user=memoss password=secrets dbname=memosdb host=db sslmode=disable" db: image: postgres:16.1 restart: unless-stopped volumes: - "./database:/var/lib/postgresql/data/" environment: POSTGRES_USER: memoss POSTGRES_PASSWORD: secrets POSTGRES_DB: memosdb Mysql 数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 services: db: image: mysql:8.1.0 container_name: db restart: always networks: - memos_network command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_general_ci - --explicit_defaults_for_timestamp=true volumes: - ./mysql:/var/lib/mysql - ./mysqlBackup:/data/mysqlBackup environment: - MYSQL_ROOT_PASSWORD=memos - MYSQL_DATABASE=memos web: image: ghcr.io/usememos/memos:latest container_name: memos restart: always networks: - memos_network volumes: - ./memos/:/var/opt/memos ports: - "5230:5230" environment: - MEMOS_DRIVER=mysql - MEMOS_DSN=root:memos@tcp(db)/memos - TZ=Asia/Chongqing depends_on: - db networks: memos_network: 1 docker compose up -d

五月 15, 2025 · 1 分钟 · 290 字 · Beiyuan ·