compose 基本操作
docker compose down # 停止并删除旧容器
docker compose up -d # 重新以新配置启动
| 命令 | 作用 |
| -------------------------------- | -------------------- |
| `docker compose ps` | 查看当前 Compose 项目的容器状态 |
| `docker compose logs -f` | 实时查看日志 |
| `docker compose exec nginx bash` | 进入指定容器 |
| `docker compose down` | 停止并清理所有容器、网络、卷 |
| `docker compose restart` | 快速重启所有容器 |
compose 进入容器
# 用服务名(compose 推荐)
docker compose exec piwigo bash
# 如果没有 bash 就用 sh
docker compose exec piwigo sh
# 或者用容器名
docker exec -it pwg_app bash
------------------------FileBrowser---------------
一、目录结构
/opt/data/
├─ user1_dir/
├─ user2_dir/
├─ user3_dir/
├─ user4_dir/
└─ (可按类目继续建子目录,如 20230614/ 备份/ WK-001-P1/ ...)
~/imgstack/
├─ docker-compose.yml
├─ nginx/
│ └─ conf.d/
│ ├─ admin.amztk.top.conf
│ └─ img.amztk.top.conf
├─ certs/
│ ├─ admin/ # admin.amztk.top 证书
│ │ ├─ fullchain.pem
│ │ └─ privkey.pem
│ └─ img/ # img.amztk.top / img.amztk.com 证书
│ ├─ fullchain.pem
│ └─ privkey.pem
└─ filebrowser/
├─ settings.json
└─ filebrowser.db # 自动生成
先创建目录:
sudo mkdir -p /opt/data/{user1_dir,user2_dir,user3_dir,user4_dir}
sudo mkdir -p ~/imgstack/nginx/conf.d ~/imgstack/certs/{admin,img}
cd ~/imgstack/filebrowser
sudo chown -R 1000:1000 ./filebrowser
sudo chown -R 1000:1000 /opt/data
在 ~/imgstack/docker-compose.yml 写入
services:
nginx:
image: nginx:1.25-alpine
container_name: img-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./certs:/etc/nginx/certs:ro
- /opt/data:/data:ro
depends_on:
- filebrowser
networks: [imgnet]
filebrowser:
image: filebrowser/filebrowser:latest
container_name: img-filebrowser
restart: unless-stopped
# 如需严格权限可改为特定 uid:gid
user: "1000:1000"
environment:
- TZ=Asia/Shanghai
volumes:
- /opt/data:/srv
- ./filebrowser:/config
command: >
--address=0.0.0.0
--port=8080
--root=/srv
--database=/config/filebrowser.db
--config=/config/settings.json
expose:
- "8080"
networks: [imgnet]
networks:
imgnet:
driver: bridge
FileBrowser 基础配置 ~/imgstack/filebrowser/settings.json:
{
"branding": {
"name": "AMZ 图库",
"disableExternal": true
},
"signup": false,
"createUserDir": false,
"commands": []
}
Nginx 配置(SSL + 反代后台 + 静态分发 + 防盗链)
后台:admin.amztk.top.conf ~/imgstack/nginx/conf.d/admin.amztk.top.conf
# 强制跳转 HTTPS
server {
listen 80;
server_name admin.amztk.top;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name admin.amztk.top;
ssl_certificate /etc/nginx/certs/admin/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/admin/privkey.pem;
client_max_body_size 200m;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://img-filebrowser:8080;
}
}
前台:img.amztk.top.conf ~/imgstack/nginx/conf.d/img.amztk.top.conf
# 兼容 .top/.com,统一跳 HTTPS
server {
listen 80;
server_name img.amztk.top img.amztk.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name img.amztk.top img.amztk.com;
ssl_certificate /etc/nginx/certs/img/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/img/privkey.pem;
# 静态根目录(只读)
root /data;
autoindex off;
# 防盗链:只允许来自本站域名与无 Referer(直链)
# 若你还有其他站点需要引用,在下方 server_names 后面追加允许的域名
set $deny_hotlink 0;
valid_referers none blocked server_names *.amztk.top *.amztk.com;
if ($invalid_referer) { set $deny_hotlink 1; }
# 仅对常见图片后缀启用缓存与防盗链
location ~* \.(?:png|jpe?g|gif|webp|svg|avif|bmp)$ {
if ($deny_hotlink) { return 403; }
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
try_files $uri =404;
}
# 其他静态资源(可选)
location / {
if ($deny_hotlink) { return 403; }
try_files $uri $uri/ =404;
}
}
如果你希望完全禁止无 Referer 的直链,把 valid_referers 里去掉 none;
如果要给 Amazon、Shopify 等站点放行引用,追加它们的域名到 valid_referers 列表中。
若想盗链时返回占位图,可把 return 403; 换成 rewrite ^ /placeholder.png last; 并把占位图放到 /opt/data/placeholder.png。
启动服务
cd ~/imgstack
docker compose down # 停止并删除旧容器
docker compose up -d # 重新以新配置启动
# 查看容器状态与日志
docker compose ps
docker compose logs -f nginx
docker compose logs -f filebrowser
修改fileBrowser admin密码
# 停止容器
docker compose stop filebrowser
# 执行命令创建用户(此时数据库不再被占用)
docker compose run --rm filebrowser sh -c \
'filebrowser -d /config/filebrowser.db -c /config/settings.json users add admin "admintpassword" --perm.admin --scope /srv'
# 启动容器
docker compose up -d
修改密码
# 停止容器(防止 DB 被占用)
docker compose stop filebrowser
# 修改 admin 密码(替换成你的密码)
docker compose run --rm filebrowser \
-d /config/filebrowser.db -c /config/settings.json \
users update admin --password "新密码"
# 启动容器
docker compose up -d filebrowser
img.amztk.top 没有权限访问图片
Nginx 的 UID(通常是 101) 授权读权限,并设置 默认 ACL,以后新文件自动继承。
# 假设 Nginx 在容器内的用户是 uid=101(nginx:nginx,Alpine 默认)
# 1) 先给现有文件/目录加读/遍历权限
sudo setfacl -R -m u:101:rX /opt/data
# 2) 给目录设置“默认 ACL”,以后新建的文件也自动给 101 读权限
sudo setfacl -R -m d:u:101:rX /opt/data
如你的 Nginx 不是 uid 101,可进入容器查:
docker compose exec nginx sh -c 'id -u nginx || id -u' 然后把上面的 101 替换成实际 UID
-------------------------Piwigo-------------------
Piwigo + Nginx 部署架构
Cloudflare (CDN + HTTPS)
↓
Nginx(反向代理 + 缓存 + 防盗链)
↓
Piwigo(图片管理 + 上传 + 分类)
↓
/data/photos (存储目录)
/opt/pwg/
docker-compose.yml
nginx/
site.conf
photos/ # 你管理的“源图”目录(按 SKU 命名/分层)
piwigo_data/ # Piwigo 程序与配置
db_data/ # 数据库持久化
1, 准备目录
mkdir -p /opt/pwg/{nginx,piwigo_data,db_data,photos,tools,nginx/cache}
2, 保存 Compose 与配置文件
/opt/pwg/docker-compose.yml
/opt/pwg/nginx/site.conf
/opt/pwg/tools/sku_links.sh
3, 将以下内容保存为 /opt/pwg/docker-compose.yml
services:
db:
image: mariadb:10.11
container_name: pwg_db
environment:
MYSQL_ROOT_PASSWORD: root_pass_123
MYSQL_DATABASE: piwigo
MYSQL_USER: piwigo
MYSQL_PASSWORD: pwg_pass_123
volumes:
- ./db:/var/lib/mysql
restart: unless-stopped
piwigo:
image: lscr.io/linuxserver/piwigo:latest
container_name: pwg_app
depends_on:
- db
environment:
PUID: 1000
PGID: 1000
TZ: Asia/Shanghai
volumes:
- ./piwigo_data:/config # 配置/缓存/日志
- ./plugins:/config/www/plugins # 可选:外挂插件目录
- ./photos:/config/www/_data/i/upload # ★ 后台上传“原图”目录(与 FTP/SFTP/Nginx 共用)
restart: unless-stopped
nginx:
image: nginx:1.25-alpine
container_name: pwg_nginx
depends_on:
- piwigo
volumes:
- ./nginx/site.conf:/etc/nginx/conf.d/default.conf:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./nginx/cache:/var/cache/nginx
- ./photos:/photos:ro # ★ 前台直链读同一目录
- ./piwigo_data:/config:ro
ports:
- "80:80"
- "443:443"
restart: unless-stopped
ftp:
image: fauria/vsftpd
container_name: pwg_ftp
environment:
- FTP_USER=amz
- FTP_PASS=yourpassword123
- PASV_ADDRESS=img.amztk.top
- PASV_MIN_PORT=21100
- PASV_MAX_PORT=21110
- LOG_STDOUT=1
# 可选:写入权限更宽松一点
- FILE_OPEN_MODE=0666
- LOCAL_UMASK=022
volumes:
- ./photos:/home/vsftpd # ★ 与 Piwigo 同目录
ports:
- "21:21"
- "21100-21110:21100-21110"
restart: unless-stopped
sftp:
image: atmoz/sftp
container_name: pwg_sftp
volumes:
- ./photos:/home/amz/upload # ★ 与 Piwigo 同目录
# 语法:user:pass:uid:gid (uid/gid 用 1000,与 Piwigo 一致)
command: amz:yourpassword123:1000:1000
ports:
- "2222:22"
restart: unless-stopped
nginx配置 保存为 /opt/pwg/nginx/site.conf
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=imgcache:200m inactive=7d max_size=20g;
# 80 -> 443
server {
listen 80;
server_name img.amztk.top;
return 301 https://img.amztk.top$request_uri;
}
server {
listen 80;
server_name admin.amztk.top;
return 301 https://admin.amztk.top$request_uri;
}
# ===============================================
# img.amztk.top — 图片直链(根路径 & 兼容 /photos/)
# ===============================================
server {
listen 443 ssl;
server_name img.amztk.top;
ssl_certificate /etc/nginx/ssl/img.crt;
ssl_certificate_key /etc/nginx/ssl/img.key;
# ① 兼容旧链接:/photos/... -> /photos/...
location ^~ /photos/ {
root /; # /photos/... 直接映射到容器 /photos/...
try_files $uri =404;
# 防盗链(保持你的逻辑)
valid_referers none blocked amztk.top *.amztk.top amazon.com *.amazon.com sellercentral.amazon.com m.media-amazon.com images-na.ssl-images-amazon.com;
# if ($invalid_referer) { return 403; }
add_header Cache-Control "public, max-age=31536000, immutable";
expires 1y;
etag on;
proxy_cache imgcache;
proxy_cache_valid 200 206 301 302 10d;
}
# ② 新增:根路径直接访问 -> 映射到 /photos
# https://img.amztk.top/2025/10/25/a.jpg => /photos/2025/10/25/a.jpg
location / {
root /photos; # 关键:把站点根映射到 /photos
try_files $uri =404;
# 同样的防盗链和缓存策略
valid_referers none blocked amztk.top *.amztk.top amazon.com *.amazon.com sellercentral.amazon.com m.media-amazon.com images-na.ssl-images-amazon.com;
# if ($invalid_referer) { return 403; }
add_header Cache-Control "public, max-age=31536000, immutable";
expires 1y;
etag on;
proxy_cache imgcache;
proxy_cache_valid 200 206 301 302 10d;
}
# 禁止脚本(覆盖根路径与 /photos/)
location ~* \.(php|sh|pl|py)$ {
return 403;
}
add_header Access-Control-Allow-Origin "*" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}
# ===============================================
# admin.amztk.top — 后台(反代到 pwg_app:80)
# ===============================================
server {
listen 443 ssl;
server_name admin.amztk.top;
ssl_certificate /etc/nginx/ssl/admin.crt;
ssl_certificate_key /etc/nginx/ssl/admin.key;
location / {
proxy_pass http://pwg_app:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
add_header X-Content-Type-Options "nosniff" always;
}
4, 准备证书
Cloudflare Origin Certificate(推荐配合 Cloudflare 的 Full (strict)):
在 Cloudflare → SSL/TLS → Origin Server → Create…
新建证书,域名填:img.example.com、admin.example.com(可以一个证书含多个主机名)。
把生成的 证书 与 私钥 分别保存为(示例):
/opt/pwg/nginx/ssl/img.crt
/opt/pwg/nginx/ssl/img.key
/opt/pwg/nginx/ssl/admin.crt
/opt/pwg/nginx/ssl/admin.key
5, 启动docker
docker compose down
docker compose up -d
Post Views: 5