Symfony GitLab CI/CD部署:如何避免覆盖public目录下的用户图片?
解决Symfony部署时用户上传图片被覆盖的方案
方案1:将用户上传目录与应用代码分离(最佳实践)
彻底隔离用户上传内容和应用版本,从根源避免覆盖问题:
- 在服务器上创建独立的持久化目录,专门存用户上传文件:
mkdir -p /var/www/$PROJECT_FOLDER/persistent/user_images - 修改Symfony配置或上传逻辑,让用户上传的图片直接写入这个持久化目录(比如调整
config/packages/framework.yaml里的文件存储路径,或者在上传业务代码里指定该目录)。 - 修改CI/CD的打包命令,排除代码仓库里的
public/images/users目录:zip -r $CI_COMMIT_SHA.zip . -x "public/images/users/*" - 更新部署脚本,在新版本目录里给
public/images/users创建软链指向持久化目录:
把原ssh命令替换成:ssh $SSH_USER@$SSH_HOST "cd /var/www/$PROJECT_FOLDER/ && unzip -q $CI_COMMIT_SHA.zip -d $CI_COMMIT_SHA && rm $CI_COMMIT_SHA.zip && ln -sfn /var/www/$PROJECT_FOLDER/persistent/user_images $CI_COMMIT_SHA/public/images/users && ln -sfn $CI_COMMIT_SHA current && exit"
以后无论怎么部署,用户上传的文件都存在独立目录里,和应用版本完全无关。
方案2:用rsync替代zip+scp,同步时排除目标目录
rsync支持差异传输,比打包上传更高效,还能直接跳过指定目录:
- 调整CI/CD的script部分,去掉zip和scp命令,改用rsync:
script: - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client rsync -y )' - rsync -avz --exclude='public/images/users' ./ $SSH_USER@$SSH_HOST:/var/www/$PROJECT_FOLDER/$CI_COMMIT_SHA/ - ssh $SSH_USER@$SSH_HOST "cd /var/www/$PROJECT_FOLDER/ && ln -sfn $CI_COMMIT_SHA current && exit"
如果需要保留现有用户图片,还可以在软链前加一步:从当前生产目录同步用户图片到新部署目录(用rsync -av current/public/images/users/ $CI_COMMIT_SHA/public/images/users/),但还是方案1的持久化方式更稳妥。
方案3:打包排除目录+部署后同步现有用户文件(临时过渡方案)
如果暂时不想调整持久化目录结构,可以用这个方式:
- 打包时排除
public/images/users目录:zip -r $CI_COMMIT_SHA.zip . -x "public/images/users/*" - 部署时,解压后从当前生产目录同步用户图片到新目录:
修改ssh命令为:ssh $SSH_USER@$SSH_HOST "cd /var/www/$PROJECT_FOLDER/ && unzip -q $CI_COMMIT_SHA.zip -d $CI_COMMIT_SHA && rm $CI_COMMIT_SHA.zip && if [ -d current/public/images/users ]; then rsync -av current/public/images/users/ $CI_COMMIT_SHA/public/images/users/; fi && ln -sfn $CI_COMMIT_SHA current && exit"
rsync只会传输差异文件,比整体移出移回的负载小很多。
内容的提问来源于stack exchange,提问作者Life4Gaming
相关产品推荐
相关产品推荐

