搜索

📄 文章 📚 合集
热门搜索
🐘 PHP ⚡ Laravel 🎨 Vue.js ⚛️ React 📦 Yii 📘 JavaScript 🗄️ MySQL 🐳 Docker
返回合集

[板块7:Docker 容器化交付] - 04 -docker 修复项目文件夹权限问题

代码示例
# 文件夹权限问题 - 完整修复流程

## 一、问题现象

服务器访问 `http://47.100.66.218:8080` 报错:

```
目录不可写:/var/www/html/storage/logs
目录不可写:/var/www/html/storage/framework
```

**原因**:容器内 PHP 进程以 `www-data` 用户运行,但 `storage` 和 `bootstrap/cache` 目录的所有者是 `root`,导致无法写入。

---

## 二、解决方案

修改 Dockerfile,在构建时创建目录并赋予 `www-data` 用户写入权限 → 重新构建镜像 → 推送到 Docker Hub → 服务器拉取并重新部署。

---

## 三、本地修改与构建(OneXPlayer 2)

### 3.1 修改 Dockerfile

**文件位置**:`D:\laragon\www\engine-api\Dockerfile`

dockerfile

FROM php:8.3-fpm-alpine

# 安装系统依赖
RUN apk add --no-cache nginx supervisor \
    && docker-php-ext-install pdo_mysql

# 复制配置文件
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# 设置工作目录
WORKDIR /var/www/html

# 复制项目文件
COPY . .

# ========== 关键修复:创建目录并设置权限 ==========
RUN mkdir -p storage/framework/sessions \
    && mkdir -p storage/framework/views \
    && mkdir -p storage/framework/cache \
    && mkdir -p storage/logs \
    && mkdir -p /var/log/supervisor \
    && chown -R www-data:www-data storage bootstrap/cache /var/log/supervisor \
    && chmod -R 775 storage bootstrap/cache /var/log/supervisor

EXPOSE 80

CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
```

### 3.2 确认 Nginx 配置文件

**文件位置**:`D:\laragon\www\engine-api\docker\nginx.conf`

nginx

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 80;
        server_name _;
        root /var/www/html/public;
        index index.php;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
}
```

### 3.3 确认 Supervisor 配置文件

**文件位置**:`D:\laragon\www\engine-api\docker\supervisord.conf`

conf

[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/run/supervisord.pid

[program:php-fpm]
command=php-fpm
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/php-fpm.log
stderr_logfile=/var/log/supervisor/php-fpm-error.log

[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx-error.log


### 3.4 本地清理、构建与测试

bash

cd D:\laragon\www\engine-api

# 查看运行的容器
docker ps -a

# 停止并删除旧容器
docker stop haozhanzhan
docker rm haozhanzhan

# 删除旧镜像
docker rmi codeyoursmile/haozhanzhan:latest

# 重新构建镜像
docker build -t codeyoursmile/haozhanzhan:latest .

# 本地测试运行
docker run -d -p 8080:80 --name haozhanzhan codeyoursmile/haozhanzhan:latest

# 验证(应返回 HTML 内容)
curl http://localhost:8080

# 测试通过后停止测试容器
docker stop haozhanzhan
docker rm haozhanzhan


## 四、推送到 Docker Hub

docker push codeyoursmile/haozhanzhan:latest

(可选)如果需要删除远程旧标签:
登录 https://hub.docker.com/u/codeyoursmile
 → 进入 `haozhanzhan` 仓库 
 → Tags → 删除 `latest`,然后再 push。


## 五、服务器部署

### 5.1 登录服务器

ssh root@你的服务器IP

### 5.2 清理旧容器与镜像

docker stop haozhanzhan
docker rm haozhanzhan
docker rmi codeyoursmile/haozhanzhan:latest


### 5.3 拉取最新镜像并运行

docker pull codeyoursmile/haozhanzhan:latest
docker run -d -p 8080:80 --name haozhanzhan codeyoursmile/haozhanzhan:latest

### 5.4 验证

docker ps
curl http://localhost:8080

浏览器打开 `http://47.100.66.218:8080`,应正常显示安装页面,不再报权限错误。

## 六、完整命令汇总(可直接复制)

### 本地执行

bash
cd D:\laragon\www\engine-api
docker ps -a
docker stop haozhanzhan
docker rm haozhanzhan
docker rmi codeyoursmile/haozhanzhan:latest
docker build -t codeyoursmile/haozhanzhan:latest .
docker push codeyoursmile/haozhanzhan:latest

### 服务器执行

bash
docker stop haozhanzhan
docker rm haozhanzhan
docker rmi codeyoursmile/haozhanzhan:latest
docker pull codeyoursmile/haozhanzhan:latest
docker run -d -p 8080:80 --name haozhanzhan codeyoursmile/haozhanzhan:latest
docker ps
curl http://localhost:8080


## 七、常见问题与解决

| 问题 | 原因 | 解决 |
|------|------|------|
| `container is using its referenced image` | 先删镜像后删容器 | 先 `docker rm 容器名`,再 `docker rmi 镜像名` |
| 删除远程镜像 | Docker CLI 不支持 | 在 Docker Hub 网页上手动删除 Tag |
| `mkdir: can't create directory` | 父目录不存在 | 使用 `mkdir -p` 递归创建 |
| `chown: unknown user www-data` | 基础镜像没有该用户 | 确认 FROM 使用的是 `php:8.3-fpm-alpine`,该镜像自带 `www-data` |
| `supervisor` 日志目录不存在 | 未提前创建 | 已在 Dockerfile 中添加 `mkdir -p /var/log/supervisor` |

---

## 八、文件清单(确保以下文件都存在)

```
D:\laragon\www\engine-api\
├── Dockerfile
├── docker/
│   ├── nginx.conf
│   └── supervisord.conf
└── 其他项目文件...
```

---

## 九、执行顺序总结

1. **本地**:修改 `Dockerfile`(添加权限和日志目录)
2. **本地**:`docker build` → `docker run` 测试 → `docker push`
3. **服务器**:`docker pull` → `docker run`
4. **验证**:浏览器访问 `http://服务器IP:8080`

🧸 adorable code

专注 PHP、JavaScript、Laravel、Vue.js、React、Yii 全栈开发。记录技术探索过程中的灵感与经验,分享工程实践洞见。

hello@adorablecode.com