Docker下ThinkPHP5的运行
一、结合 Apache 的基本运行#
tp5 下载地址:http://www.thinkphp.cn/down.html
创建目录 tp5,再分别创建 compose 文件夹(存放 compose 配置文件)和 web 文件夹(存放 tp5),然后使用 unzip 将 tp5 解压到 tp5/web 目录下。
一般来说可以将 Public 目录作为网站根目录,Apache 中只要挂载 Public 目录,Fpm 中则需要挂载整个目录。
1.1 Compose 编排#
docker-compose.yml:
version: "3" services: fpm: image: php:7.2.2-fpm-alpine container_name: fpm volumes: - /home/txl/tp5/web:/php networks: mywebnet: ipv4_address: 192.148.0.2 httpd: image: httpd:2.4.33-alpine container_name: httpd ports: - 80:80 volumes: - /home/txl/tp5/web/public:/usr/local/apache2/htdocs/ - /home/txl/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf networks: mywebnet: ipv4_address: 192.148.0.3 networks: mywebnet: driver: bridge ipam: config: - subnet: 192.148.0.0/16
需要注意 vhosts 中配置的反向代理Ip和Fpm内网Ip的一致性:
启动:
docker-compose up -d
二、URL 重写#
1、httpd.conf 配置文件开启 mod_rewrite.so 模块
2、修改 vhost
3、重启容器
docker-compose restart
三、MySQL 数据库连接#
修改 docker-compose.yml,将 MySQL 服务加入编排:
mysql: image: mysql:5.7.22 container_name: mysqld ports: - 3306:3306 volumes: - /home/txl/mysql/conf:/etc/mysql/conf.d - /home/txl/mysql/data:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=123 networks: mywebnet: ipv4_address: 192.148.0.4
在 TP 数据库配置文件 application/database.php 中修改相应配置,写一个数据库连接测试方法:
<?php namespace app\index\controller; use think\Db; class Index { public function test() { $get_users = Db::table('user')->select(); var_export($get_users); } }
访问:
四、Redis 交互#
- redis 镜像地址:https://hub.docker.com/_/redis
- 初始配置模板:https://redis.io/topics/config
修改 redis 基本配置:
bind 0.0.0.0 # 所有IP可连 dir /data # redis数据目录 ...
修改 docker-compose.yml,将 Redis 服务加入编排:
redis: image: redis:4-alpine container_name: redis ports: - 6379:6379 volumes: - /home/txl/conf/redis.conf:/usr/local/etc/redis/redis.conf - /home/txl/tp5/redisdata:/data networks: mywebnet: ipv4_address: 192.138.0.5
在 TP 配置文件 application/config.php 中修改 Reids 配置:
'cache' => [ // 驱动方式 'type' => 'redis', 'host' => '180.76.232.93', 'port' => '6379', // 缓存保存目录 //'path' => CACHE_PATH, // 缓存前缀 'prefix' => '', // 缓存有效期 0表示永久缓存 'expire' => 0, ],
写一个测试方法,判断 redis 中是否有用户列表,有则返回,无则从数据库读取并存入 redis:
<?php namespace app\index\controller; use think\Db; use think\Cache; class Index { public function test() { $get_users = Cache::get("user"); if(!$get_users) { $get_users = Db::table('user')->select(); Cache::set("user",$get_users,200); } return $get_users; } }
访问:
进入 redis 容器查看刚刚存放进来数据:
如果报以下错误说明 fpm 容器尚未安装 redis 扩展:
扩展安装套路和上面安装 pdo_mysql 差不多,但是 redis 扩展需要使用 pecl 安装。dockerfile 如下:
FROM php:7.2.2-fpm-alpine RUN apk add autoconf gcc g++ make RUN pecl install redis-4.0.0 \ && docker-php-ext-enable redis
然后就是修改 docker-compose.yml 文件下的相应 build 节点,执行 docker build,最后删除并重启容器。
五、alpine 容器下的权限问题#
创建文件上传表单:
<form action="/index/index/upload" enctype="multipart/form-data" method="post"> <input type="file" name="image" /> <br> <input type="submit" value="上传" /> </form>
upload 接收处理方法:
public function upload(){ // 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 移动到框架应用根目录/uploads/ 目录下 $info = $file->move( '../uploads'); if($info){ // 成功上传后 获取上传信息 // 输出 jpg echo $info->getExtension(); // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg echo $info->getSaveName(); // 输出 42a79759f284b767dfcb2a0197904287.jpg echo $info->getFilename(); }else{ // 上传失败获取错误信息 echo $file->getError(); } }
执行报错:
进入 fpm 容器,之前将程序根目录映射到 /php 下,查看该目录文件:
可以发现,网站程序目录下所有文件所属的用户和用户组都是1000。这是因为之前执行创建 fpm 容器时的用户是我新建的用户 txl,而它的 uid 以及 gid 正好都是1000:
而 fpm 容器中执行操作的默认用户是 www-data,它的 uid 和 gid 都是82。因此该用户自然无权限操作网站程序目录的文件:
解决:将 www-data 用户的 uid 以及 gid 修改为1000:
usermod -u 1000 www-data groupmod -g 1000 www-data
but,基于 alpine 的容器默认没有这两个命令,需要先执行命令:
apk --no-cache add shadow
另外,在 alpine3.4 或更早版本,首先还需要加入数据源然后在执行上面的命令:
echo http://nl.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories
修改 uid 和 gid 成功后,需要重启该容器,然后就可以正常访问了:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端