迁移原因
- 经济问题:服务器到期,续费太贵,换便宜机器
- 必要性:有一些网站还使用了这个图床,仍有保留的必要。
- 换docker: 不需要适配php,数据库等,后续迁移更方便了
迁移过程说明
基本情况
- 原机器:
- 系统:centos 7.6
- php 7.4
- mariadb 10.2.41
- chevereto-free 1.6.2
- 新机器:采用docker-compose, 安装docker版本,并带上数据库
- 系统:debian 12
- docker的版本是:
nmtan/chevereto
- mariadb版本:10.2.41
采用docker-compose实现一键安装部署,后续迁移都会方便很多,这个过程也踩了坑,记录下来,以备后续查阅。参考链接3中有提到mariadb版本要往高的升,不要使用低于原版本的。
迁移过程
原机器上的操作:
备份chevereto文件
最重要的是images目录和app/settings.php这两个。
去哪里可以找到chevereto安装目录?
一般去nginx目录中看,找到nginx目录,去看root这一行的路径,一般就是安装目录。假定在/var/www/html/chevereto
目录中。
tar -czvf chevereto_files_backup.tar.gz /var/www/html/chevereto
备份数据库
一般用户名与数据库名都会定为chevereto,要记得准备好chevereto用户的数据库密码。
#mysqldump -u 数据库用户名 -p 数据库名 > chevereto_db_backup.sql
mysqldump -u chevereto -p chevereto > chevereto_db_backup.sql
下载文件
把上面的两个文件下载到你的本地。chevereto_db_backup.sql
和chevereto_files_backup.tar.gz
这两个文件,到时候上传到新服务器目录上。
新机器操作
默认说明
- 默认已经安装好docker
- 安装好docker-compose
准备docker-compose配置文件
配置文件如下,需要自己修改对应的数据库用户名,密码,数据库名等,根据自己的要求进行调整即可。
services:
db:
image: mariadb:10.2.41
volumes:
- ./database:/var/lib/mysql:rw
restart: always
networks:
- app-network
environment:
- 'MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD}'
- MYSQL_DATABASE=chevereto
- MYSQL_USER=chevereto
- 'MYSQL_PASSWORD=password'
ports:
- 3306:3306
chevereto:
depends_on:
- db
image: nmtan/chevereto
restart: always
networks:
- app-network
environment:
- CHEVERETO_DB_HOST=db
- CHEVERETO_DB_USERNAME=chevereto
- 'CHEVERETO_DB_PASSWORD=password'
- 'CHEVERETO_DB_NAME=chevereto'
- CHEVERETO_DB_PREFIX=chv_
volumes:
- ./html:/var/www/html:rw
- ./html/images:/var/www/html/images:rw
- ./php.ini:/usr/local/etc/php/php.ini:ro
ports:
- 8086:80
networks:
app-network:
准备相关文件
# 创建项目文件
mkdir -p /root/chevereto
cd /root/chevereto
#创建数据库加载目录和chevereto目录
mkdir database
mkdir html
在当前准备一个php.ini文件,代码如下:
memory_limit = 256M;
upload_max_filesize = 100M;
post_max_size = 100M;
启动docker
启动docker-compose
docker-compose up -d
查看容器状态
docker-compose ps # 查看该项目对应的容器状态,这个没有容器ID
docker ps # 查看当前存在的容器状态
docker ps -a #查看所有容器,包括停止的
如果正常的话,可以进行下一步了。
恢复文件和数据库
恢复文件 images
将之前的chevereto_db_backup.sql
和chevereto_files_backup.tar.gz
上传到chevereto目录中。
tar -zxvf chevereto_files_backup.tar.gz
#把这个解压出来文件中的images 复制到html目录中的images中进行覆盖
app/settings.php修改
修改setting.php文件,在html/app/目录下
原主机上db_host应该是localhost
,因为我们使用了容器,所以需要修改成以下代码,修改成db
.跟之前docker-compose中的services下的db那个名称是一样的。表示使用容器中的数据库。
'db_host' => 'db',
检查文件权限问题
# 一般给www-data:root即可
chown -R www-data:root html/
恢复数据库
cat chevereto_db_backup.sql | docker exec -i your_project_db_1 mysql -u chevereto -p your_db_password chevereto
- your_project_db_1 : 使用docker-compose ps 查看,可以看到数据库容器的名称,替换这个
- your_db_password:这个是你之前在docker-compose.yml中设置的用户密码,用单引号括起来即可。
- 上面这一步是把数据存放到数据库中。
重新启动容器
docker-compose restart
#查看日志
docker-compose logs -f
配置nginx并设置好dns解析
server {
listen 443 ssl http2;
server_name your.domain;
# SSL 配置
ssl_certificate /to/path/your.domain.crt;
ssl_certificate_key /to/path/your.domain.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 2h;
ssl_buffer_size 16k;
ssl_session_tickets off;
# 客户端最大上传大小
client_max_body_size 100M;
# 日志配置(可选)
access_log /var/log/nginx/your.domain.log;
error_log /var/log/nginx/your.domain.log;
# 反向代理到 Docker 容器
location / {
proxy_pass http://127.0.0.1:8086; # 指向 Chevereto Docker 容器的地址和端口
proxy_http_version 1.1;
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_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
}
# 禁止访问敏感文件或目录
location ~* /(app|content|lib)/.*\.(po|php|lock|sql)$ {
deny all;
}
# CORS 头设置
location ~* \.(ttf|ttc|otf|eot|woff|woff2|css|js)$ {
add_header Access-Control-Allow-Origin "*";
proxy_pass http://127.0.0.1:8086;
}
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/javascript application/json text/css text/plain application/xml;
# robots.txt
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
proxy_pass http://127.0.0.1:8086;
}
}
server {
listen 80;
server_name your.domain;
return 301 https://$server_name$request_uri;
}
- 需要自己修改域名信息server_name,并做好DNS解析
- 修改证书路径:ssl_certificate和ssl_certificate_key
- 修改代理的端口号,与yml文件中设置的chevereto保持一致
迁移问题
遇到的问题
数据库导入成功,images目录也复制过去了,但是chevereto网页上对于任意图片都是展示的黑色的。
解决过程
- 是images目录没有挂载成功,导致docker中无法识别到正确的图片
- 上传了一张图,发现上传的图片能正常显示,说明程序是正常运行的
- 根据正常显示的图片,在宿主机对应目录,没有发现对应的图片
- 去docker容器中,发现有找到新上传的图片,但是没有旧的图片
- 在宿主机对应的目录中创建文本文件,在docker中可以找到,在docker中修改该文件,在宿主机中也能看到对应的修改内容。
- 所以,可以判断出数据库成功导入,但是images目录挂载有问题
docker卷问题
- 这个镜像有一个匿名卷挂载,在匿名卷没有显式挂载时,docker会自动创建匿名卷以保护数据安全
- 也就是因为之前创建的时候,没有显式挂载images这个目录,导致挂载了匿名卷,从而导致images迁移后并没有同步到docker中。
补充知识
如何查看匿名卷?
- 查看镜像,找到对应的image ID
- 根据ID去查看卷的信息
- 查找volumnes相关内容:
docker images
#假定docker image的id为:80a11a69ffrt
docker inspect 80a11a69ffrt
查看到的内容如下,可以看到images这个目录,已经被当成匿名卷了。
"Volumes": {
"/var/www/html/images": {}
},
运行容器时的挂载优先级
- 显式挂载 > 匿名卷 > 镜像中原始目录内容
- 如果显式挂载了宿主机目录,则优先使用宿主机数据;否则使用匿名卷,最后才是镜像中定义的内容。