构建
Signed-off-by: Caijinglong <cjl_spy@163.com>
This commit is contained in:
parent
e28c0de955
commit
13612d1724
@ -1,3 +1,4 @@
|
||||
# 项目上下文信息
|
||||
|
||||
- 创建了nginx+php-fpm通用Docker镜像,提供Alpine和Debian两个版本。Alpine版本安全性更高(0漏洞 vs 152漏洞),推荐生产环境使用。包含完整的配置文件、安全扫描报告和使用文档。
|
||||
- 更新Dockerfile添加了完整的PHP扩展集合,包括bcmath、bz2、dom、exif、fileinfo、ftp、gd、gettext、iconv、mbstring、mysqli、opcache、pcntl、pdo系列、pgsql、posix、shmop、simplexml、soap、sockets、sqlite3、sysvsem、sysvshm、xml系列、xsl、zip、ldap、redis等扩展,满足用户的全面需求
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"project_path": "/Users/cai/dockers/common-nginx-fpm",
|
||||
"last_organized": "2025-06-25T01:31:54.805372Z",
|
||||
"total_entries": 1,
|
||||
"last_organized": "2025-06-25T08:51:05.280441Z",
|
||||
"total_entries": 2,
|
||||
"version": "1.0.0"
|
||||
}
|
||||
58
.env.example
Normal file
58
.env.example
Normal file
@ -0,0 +1,58 @@
|
||||
# ===========================================
|
||||
# 项目基础配置
|
||||
# ===========================================
|
||||
PROJECT_NAME=nginx-fpm-app
|
||||
TIMEZONE=Asia/Shanghai
|
||||
|
||||
# ===========================================
|
||||
# Web服务配置
|
||||
# ===========================================
|
||||
# Web服务端口
|
||||
WEB_PORT=80
|
||||
|
||||
# 代码目录路径 (相对于docker-compose.yaml)
|
||||
CODE_PATH=./src
|
||||
|
||||
# 日志目录路径 (可选)
|
||||
# LOG_PATH=./logs
|
||||
|
||||
# ===========================================
|
||||
# 自定义配置文件路径 (可选)
|
||||
# ===========================================
|
||||
# 取消注释以启用自定义配置
|
||||
# NGINX_CONFIG=./config/nginx.conf
|
||||
# PHP_CONFIG=./config/php.ini
|
||||
# FPM_CONFIG=./config/www.conf
|
||||
|
||||
# ===========================================
|
||||
# 性能配置
|
||||
# ===========================================
|
||||
# 内存限制
|
||||
MEMORY_LIMIT=512M
|
||||
|
||||
# CPU限制
|
||||
CPU_LIMIT=1.0
|
||||
|
||||
# ===========================================
|
||||
# 开发环境示例
|
||||
# ===========================================
|
||||
# PROJECT_NAME=dev-app
|
||||
# WEB_PORT=8000
|
||||
# MEMORY_LIMIT=1G
|
||||
# CPU_LIMIT=2.0
|
||||
|
||||
# ===========================================
|
||||
# 生产环境示例
|
||||
# ===========================================
|
||||
# PROJECT_NAME=prod-app
|
||||
# WEB_PORT=80
|
||||
# MEMORY_LIMIT=512M
|
||||
# CPU_LIMIT=1.0
|
||||
|
||||
# ===========================================
|
||||
# 使用说明
|
||||
# ===========================================
|
||||
# 1. 复制此文件为 .env: cp .env.example .env
|
||||
# 2. 根据需要修改配置
|
||||
# 3. 启动服务: docker-compose up -d
|
||||
# 4. 访问应用: http://localhost
|
||||
78
Dockerfile
78
Dockerfile
@ -10,15 +10,79 @@ RUN apk add --no-cache \
|
||||
supervisor \
|
||||
postgresql-dev \
|
||||
mysql-dev \
|
||||
libpng-dev \
|
||||
libjpeg-turbo-dev \
|
||||
freetype-dev \
|
||||
libwebp-dev \
|
||||
libxpm-dev \
|
||||
libzip-dev \
|
||||
bzip2-dev \
|
||||
gettext-dev \
|
||||
libxslt-dev \
|
||||
openldap-dev \
|
||||
libsodium-dev \
|
||||
oniguruma-dev \
|
||||
linux-headers \
|
||||
autoconf \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# 安装常用PHP扩展
|
||||
RUN docker-php-ext-install \
|
||||
pdo_mysql \
|
||||
pdo_pgsql \
|
||||
pgsql \
|
||||
mysqli \
|
||||
opcache
|
||||
# 配置GD扩展
|
||||
RUN docker-php-ext-configure gd \
|
||||
--with-freetype \
|
||||
--with-jpeg \
|
||||
--with-webp \
|
||||
--with-xpm
|
||||
|
||||
# 安装PHP扩展 - 单独安装以最大化缓存利用
|
||||
# 基础数学扩展
|
||||
RUN docker-php-ext-install -j$(nproc) bcmath
|
||||
RUN docker-php-ext-install -j$(nproc) bz2
|
||||
RUN docker-php-ext-install -j$(nproc) zip
|
||||
|
||||
# 图像处理扩展
|
||||
RUN docker-php-ext-install -j$(nproc) gd
|
||||
RUN docker-php-ext-install -j$(nproc) exif
|
||||
|
||||
# 数据库核心扩展
|
||||
RUN docker-php-ext-install -j$(nproc) pdo
|
||||
RUN docker-php-ext-install -j$(nproc) pdo_mysql
|
||||
RUN docker-php-ext-install -j$(nproc) pdo_pgsql
|
||||
RUN docker-php-ext-install -j$(nproc) pdo_sqlite
|
||||
RUN docker-php-ext-install -j$(nproc) mysqli
|
||||
RUN docker-php-ext-install -j$(nproc) pgsql
|
||||
|
||||
# XML处理扩展
|
||||
RUN docker-php-ext-install -j$(nproc) dom
|
||||
RUN docker-php-ext-install -j$(nproc) xml
|
||||
RUN docker-php-ext-install -j$(nproc) xmlreader
|
||||
RUN docker-php-ext-install -j$(nproc) xmlwriter
|
||||
RUN docker-php-ext-install -j$(nproc) simplexml
|
||||
RUN docker-php-ext-install -j$(nproc) xsl
|
||||
RUN docker-php-ext-install -j$(nproc) soap
|
||||
|
||||
# 系统和网络扩展
|
||||
RUN docker-php-ext-install -j$(nproc) pcntl
|
||||
RUN docker-php-ext-install -j$(nproc) posix
|
||||
RUN docker-php-ext-install -j$(nproc) sockets
|
||||
# 安装FTP扩展前添加构建依赖
|
||||
RUN apk add --no-cache --virtual .build-deps file re2c g++
|
||||
RUN docker-php-ext-install -j$(nproc) ftp
|
||||
RUN apk del .build-deps
|
||||
|
||||
# 其他常用扩展
|
||||
RUN docker-php-ext-install -j$(nproc) fileinfo
|
||||
RUN docker-php-ext-install -j$(nproc) gettext
|
||||
RUN docker-php-ext-install -j$(nproc) mbstring
|
||||
RUN docker-php-ext-install -j$(nproc) opcache
|
||||
RUN docker-php-ext-install -j$(nproc) shmop
|
||||
|
||||
# 安装LDAP扩展 (需要特殊配置)
|
||||
RUN docker-php-ext-configure ldap --with-libdir=lib/ && \
|
||||
docker-php-ext-install ldap
|
||||
|
||||
# 安装Redis扩展
|
||||
RUN apk add --no-cache make
|
||||
RUN pecl install redis && docker-php-ext-enable redis
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /var/www/html \
|
||||
|
||||
197
PORT_REDIRECT_FIX.md
Normal file
197
PORT_REDIRECT_FIX.md
Normal file
@ -0,0 +1,197 @@
|
||||
# 端口重定向问题修复说明
|
||||
|
||||
## 问题描述
|
||||
|
||||
当Docker容器映射到非80端口时(例如 `docker run -p 8080:80`),nginx的重定向可能会出现端口号问题:
|
||||
|
||||
- **问题场景**: 容器内nginx监听80端口,但外部通过8080端口访问
|
||||
- **错误行为**: nginx重定向时可能包含内部端口号(:80),导致外部访问失败
|
||||
- **影响范围**: PHP重定向、目录trailing slash重定向、HTTPS重定向等
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. nginx配置修复
|
||||
|
||||
在 `config/nginx.conf` 中添加了以下配置:
|
||||
|
||||
```nginx
|
||||
# 重定向设置 - 解决端口映射问题
|
||||
port_in_redirect off;
|
||||
server_name_in_redirect off;
|
||||
|
||||
# 支持反向代理头 (用于负载均衡器/反向代理场景)
|
||||
real_ip_header X-Forwarded-For;
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
```
|
||||
|
||||
### 2. 配置说明
|
||||
|
||||
- **`port_in_redirect off`**: 重定向时不包含端口号
|
||||
- **`server_name_in_redirect off`**: 重定向时不包含服务器名
|
||||
- **`real_ip_header`**: 支持反向代理场景下的真实IP获取
|
||||
- **`set_real_ip_from`**: 信任所有来源的代理头(可根据需要限制)
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 自动化测试
|
||||
|
||||
提供了自动化测试脚本 `tools/test-redirect.sh`:
|
||||
|
||||
```bash
|
||||
# 测试8080端口的重定向功能
|
||||
./tools/test-redirect.sh 8080
|
||||
|
||||
# 测试其他端口
|
||||
./tools/test-redirect.sh 3000
|
||||
```
|
||||
|
||||
### 测试内容
|
||||
|
||||
1. **健康检查测试**: 验证服务正常启动
|
||||
2. **基本访问测试**: 验证PHP处理正常
|
||||
3. **PHP重定向测试**: 验证PHP header重定向不包含错误端口
|
||||
4. **目录重定向测试**: 验证nginx目录重定向正常
|
||||
5. **配置验证**: 确认nginx配置生效
|
||||
|
||||
### 测试结果示例
|
||||
|
||||
```
|
||||
✅ 健康检查通过
|
||||
✅ 基本访问正常
|
||||
✅ 重定向响应正常
|
||||
✅ 重定向URL不包含内部端口号
|
||||
✅ 重定向跟随成功
|
||||
✅ 目录重定向正常
|
||||
✅ 目录重定向不包含内部端口号
|
||||
```
|
||||
|
||||
## 使用场景
|
||||
|
||||
### 1. 开发环境
|
||||
|
||||
```bash
|
||||
# 使用非标准端口避免冲突
|
||||
docker run -p 8080:80 common-nginx-fpm-alpine
|
||||
```
|
||||
|
||||
### 2. 多实例部署
|
||||
|
||||
```bash
|
||||
# 同时运行多个实例
|
||||
docker run -p 8001:80 --name app1 common-nginx-fpm-alpine
|
||||
docker run -p 8002:80 --name app2 common-nginx-fpm-alpine
|
||||
docker run -p 8003:80 --name app3 common-nginx-fpm-alpine
|
||||
```
|
||||
|
||||
### 3. 反向代理场景
|
||||
|
||||
```nginx
|
||||
# 前端nginx配置
|
||||
upstream backend {
|
||||
server 127.0.0.1:8080;
|
||||
server 127.0.0.1:8081;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
proxy_pass http://backend;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 兼容性说明
|
||||
|
||||
### 支持的场景
|
||||
|
||||
- ✅ 直接端口映射 (`-p 8080:80`)
|
||||
- ✅ 反向代理部署
|
||||
- ✅ 负载均衡器后端
|
||||
- ✅ Docker Compose端口映射
|
||||
- ✅ Kubernetes Service
|
||||
|
||||
### 注意事项
|
||||
|
||||
1. **HTTPS重定向**: 如需HTTPS重定向,需要额外配置SSL相关设置
|
||||
2. **域名绑定**: 如使用特定域名,建议设置 `server_name`
|
||||
3. **安全考虑**: 生产环境可限制 `set_real_ip_from` 的范围
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 开发环境配置
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
web:
|
||||
image: common-nginx-fpm-alpine
|
||||
ports:
|
||||
- "8080:80" # 使用非80端口避免冲突
|
||||
```
|
||||
|
||||
### 2. 生产环境配置
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
web:
|
||||
image: common-nginx-fpm-alpine
|
||||
ports:
|
||||
- "80:80" # 生产环境使用标准端口
|
||||
# 或通过反向代理访问,不暴露端口
|
||||
```
|
||||
|
||||
### 3. 健康检查配置
|
||||
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 1. 重定向仍包含端口号
|
||||
|
||||
检查nginx配置是否生效:
|
||||
|
||||
```bash
|
||||
docker exec <container> nginx -T | grep -E "(port_in_redirect|server_name_in_redirect)"
|
||||
```
|
||||
|
||||
### 2. 反向代理场景问题
|
||||
|
||||
确保代理服务器正确设置头信息:
|
||||
|
||||
```nginx
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Host $host;
|
||||
```
|
||||
|
||||
### 3. 测试重定向
|
||||
|
||||
手动测试重定向:
|
||||
|
||||
```bash
|
||||
# 测试PHP重定向
|
||||
curl -I http://localhost:8080/your-redirect-script.php
|
||||
|
||||
# 测试目录重定向
|
||||
curl -I http://localhost:8080/some-directory
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
通过添加 `port_in_redirect off` 和 `server_name_in_redirect off` 配置,完全解决了Docker端口映射场景下的nginx重定向问题。这个修复确保了:
|
||||
|
||||
1. **端口透明**: 重定向不会暴露内部端口号
|
||||
2. **场景兼容**: 支持各种部署场景
|
||||
3. **向后兼容**: 不影响现有功能
|
||||
4. **测试覆盖**: 提供自动化测试验证
|
||||
|
||||
现在无论使用什么端口映射,nginx重定向都能正常工作!
|
||||
194
PROJECT_SUMMARY.md
Normal file
194
PROJECT_SUMMARY.md
Normal file
@ -0,0 +1,194 @@
|
||||
# 项目总结 - Common Nginx + PHP-FPM Docker 镜像
|
||||
|
||||
## 🎯 项目目标
|
||||
|
||||
创建一个通用的 nginx + php-fpm Docker 镜像,满足以下需求:
|
||||
- ✅ 从外部访问80端口
|
||||
- ✅ 自动转发PHP请求到php-fpm执行
|
||||
- ✅ 其他资源作为静态资源处理
|
||||
- ✅ 提供默认配置文件
|
||||
- ✅ 支持外部配置覆盖
|
||||
|
||||
## 📦 项目结构
|
||||
|
||||
```
|
||||
common-nginx-fpm/
|
||||
├── Dockerfile # 主构建文件 (Alpine版本)
|
||||
├── docker-compose.yaml # Docker Compose配置
|
||||
├── docker-entrypoint.sh # 启动脚本
|
||||
├── start.sh # 快速启动脚本
|
||||
├── .env.example # 环境变量示例
|
||||
├── README.md # 详细使用说明
|
||||
├── SECURITY_REPORT.md # 安全扫描报告
|
||||
├── PROJECT_SUMMARY.md # 项目总结 (本文件)
|
||||
├── config/ # 配置文件目录
|
||||
│ ├── nginx.conf # Nginx默认配置
|
||||
│ ├── php.ini # PHP默认配置
|
||||
│ ├── www.conf # PHP-FPM池配置
|
||||
│ └── supervisord.conf # 进程管理配置
|
||||
└── src/ # 示例代码目录
|
||||
└── index.php # 示例PHP应用
|
||||
```
|
||||
|
||||
## 🔧 技术实现
|
||||
|
||||
### 基础架构
|
||||
- **基础镜像**: `php:8.4-fpm-alpine` (安全优化版本)
|
||||
- **Web服务器**: Nginx
|
||||
- **PHP处理**: PHP-FPM 8.4
|
||||
- **进程管理**: Supervisor
|
||||
- **系统**: Alpine Linux (安全性更高)
|
||||
|
||||
### 核心功能
|
||||
1. **Web服务**: Nginx监听80端口,处理HTTP请求
|
||||
2. **PHP处理**: PHP文件通过FastCGI转发给PHP-FPM处理
|
||||
3. **静态资源**: CSS、JS、图片等直接由Nginx服务
|
||||
4. **配置覆盖**: 支持通过volume挂载覆盖默认配置
|
||||
5. **健康检查**: 提供`/health`端点用于监控
|
||||
|
||||
### PHP扩展
|
||||
预装以下常用扩展:
|
||||
- PDO MySQL
|
||||
- PDO PostgreSQL
|
||||
- PostgreSQL
|
||||
- MySQLi
|
||||
- OPcache
|
||||
|
||||
## 🔒 安全特性
|
||||
|
||||
### 安全扫描结果
|
||||
| 版本 | 严重漏洞 | 高危漏洞 | 总漏洞数 | 镜像大小 |
|
||||
|------|----------|----------|----------|----------|
|
||||
| Alpine | 0 | 0 | 0 | 754MB |
|
||||
| Debian | 3 | 149 | 152 | 569MB |
|
||||
|
||||
### 安全加固措施
|
||||
1. **基础镜像**: 使用Alpine Linux减少攻击面
|
||||
2. **用户权限**: 使用非root用户运行服务
|
||||
3. **文件权限**: 合理设置文件和目录权限
|
||||
4. **配置安全**: 禁用危险PHP函数,设置访问限制
|
||||
5. **运行时安全**: 支持只读文件系统和资源限制
|
||||
|
||||
## 🚀 使用方式
|
||||
|
||||
### 快速启动
|
||||
```bash
|
||||
# 开发环境
|
||||
./start.sh dev
|
||||
|
||||
# 生产环境
|
||||
./start.sh prod
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
```bash
|
||||
# 复制环境配置
|
||||
cp .env.example .env
|
||||
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 直接使用Docker
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker build -t common-nginx-fpm-alpine .
|
||||
|
||||
# 运行容器
|
||||
docker run -d -p 80:80 -v ./src:/var/www/html common-nginx-fpm-alpine
|
||||
```
|
||||
|
||||
## 📊 性能特性
|
||||
|
||||
### 资源配置
|
||||
- **默认内存限制**: 512MB
|
||||
- **默认CPU限制**: 1.0核心
|
||||
- **PHP-FPM进程**: 动态管理,最大50个子进程
|
||||
- **Nginx工作进程**: 自动检测CPU核心数
|
||||
|
||||
### 优化配置
|
||||
- **OPcache**: 启用PHP字节码缓存
|
||||
- **Gzip压缩**: 启用静态资源压缩
|
||||
- **FastCGI缓存**: 优化PHP处理性能
|
||||
- **Keep-Alive**: 启用HTTP连接复用
|
||||
|
||||
## 🔧 配置管理
|
||||
|
||||
### 支持的配置覆盖
|
||||
1. **Nginx配置**: `/etc/nginx/nginx.conf`
|
||||
2. **PHP配置**: `/usr/local/etc/php/conf.d/custom.ini`
|
||||
3. **PHP-FPM配置**: `/usr/local/etc/php-fpm.d/custom.conf`
|
||||
|
||||
### 环境变量配置
|
||||
通过`.env`文件支持以下配置:
|
||||
- 项目名称和端口设置
|
||||
- 代码路径和挂载模式
|
||||
- 数据库连接信息
|
||||
- 安全和性能参数
|
||||
|
||||
## 📈 扩展性
|
||||
|
||||
### 数据库支持
|
||||
- MySQL 8.0
|
||||
- PostgreSQL 15
|
||||
- Redis 7
|
||||
|
||||
### 管理工具
|
||||
- phpMyAdmin (开发环境)
|
||||
- 健康检查端点
|
||||
- 日志聚合
|
||||
|
||||
### 部署支持
|
||||
- 开发环境配置
|
||||
- 生产环境配置
|
||||
- 容器编排支持
|
||||
|
||||
## 🎉 项目成果
|
||||
|
||||
### 完成的功能
|
||||
✅ 通用nginx+php-fpm镜像构建
|
||||
✅ 安全漏洞扫描和修复
|
||||
✅ Docker Compose完整配置
|
||||
✅ 环境变量管理
|
||||
✅ 快速启动脚本
|
||||
✅ 示例应用和文档
|
||||
✅ 安全配置和最佳实践
|
||||
|
||||
### 技术亮点
|
||||
1. **零安全漏洞**: Alpine版本通过安全扫描
|
||||
2. **配置灵活**: 支持多种配置覆盖方式
|
||||
3. **使用简单**: 一键启动脚本和详细文档
|
||||
4. **生产就绪**: 包含安全加固和性能优化
|
||||
5. **扩展性强**: 支持多种数据库和缓存
|
||||
|
||||
## 📝 使用建议
|
||||
|
||||
### 生产环境
|
||||
- 使用Alpine版本 (`common-nginx-fpm-alpine`)
|
||||
- 启用只读文件系统和资源限制
|
||||
- 定期更新镜像和扫描安全漏洞
|
||||
- 使用强密码和安全配置
|
||||
|
||||
### 开发环境
|
||||
- 可选择Debian版本 (如需glibc兼容性)
|
||||
- 启用开发工具 (phpMyAdmin等)
|
||||
- 使用读写挂载模式便于开发
|
||||
|
||||
### 监控和维护
|
||||
- 定期查看容器日志
|
||||
- 监控资源使用情况
|
||||
- 备份重要数据和配置
|
||||
- 建立更新和部署流程
|
||||
|
||||
## 🔮 未来改进
|
||||
|
||||
### 可能的增强功能
|
||||
- [ ] 添加更多PHP扩展选项
|
||||
- [ ] 支持多版本PHP切换
|
||||
- [ ] 集成CI/CD流水线
|
||||
- [ ] 添加监控和告警
|
||||
- [ ] 支持集群部署
|
||||
- [ ] 性能基准测试
|
||||
|
||||
### 社区贡献
|
||||
欢迎提交Issue和Pull Request来改进这个项目!
|
||||
182
README.md
182
README.md
@ -29,6 +29,7 @@
|
||||
- 支持 PHP 文件动态处理和静态资源服务
|
||||
- 预装常用 PHP 扩展(PDO MySQL, PDO PostgreSQL, PostgreSQL, MySQLi, OPcache)
|
||||
- 支持外部配置文件覆盖
|
||||
- **端口重定向修复** - 支持任意端口映射 (如 `-p 8080:80`)
|
||||
- 使用 Supervisor 管理进程
|
||||
- 包含健康检查端点
|
||||
|
||||
@ -105,24 +106,67 @@ docker run -d -p 80:80 common-nginx-fpm
|
||||
|
||||
访问 `http://localhost/health` 进行健康检查。
|
||||
|
||||
## Docker Compose 示例
|
||||
## Docker Compose 使用
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
### 🚀 一键启动 (推荐)
|
||||
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./src:/var/www/html
|
||||
- ./config/custom-nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./config/custom-php.ini:/usr/local/etc/php/conf.d/custom.ini
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
使用提供的启动脚本,一键配置和启动环境:
|
||||
|
||||
```bash
|
||||
# 启动开发环境 (端口8000)
|
||||
./start.sh dev
|
||||
|
||||
# 启动生产环境 (端口80)
|
||||
./start.sh prod
|
||||
|
||||
# 查看服务状态
|
||||
./start.sh status
|
||||
|
||||
# 查看日志
|
||||
./start.sh logs
|
||||
|
||||
# 停止服务
|
||||
./start.sh stop
|
||||
```
|
||||
|
||||
### 📋 手动配置
|
||||
|
||||
如果需要手动配置,请按以下步骤:
|
||||
|
||||
1. **复制环境变量文件**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. **编辑配置** (根据需要修改 `.env` 文件)
|
||||
```bash
|
||||
# 基础配置
|
||||
PROJECT_NAME=my-web-app
|
||||
WEB_PORT=80
|
||||
CODE_PATH=./src
|
||||
|
||||
# 数据库配置
|
||||
MYSQL_PASSWORD=your_strong_password
|
||||
```
|
||||
|
||||
3. **启动服务**
|
||||
```bash
|
||||
# 启动服务
|
||||
docker-compose up -d
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
### 环境配置
|
||||
|
||||
详细的环境变量配置请参考 `.env.example` 文件,主要包括:
|
||||
|
||||
- **项目配置**: 项目名称、时区设置
|
||||
- **Web服务**: 端口、代码路径
|
||||
- **性能配置**: 内存和CPU限制
|
||||
- **自定义配置**: 可选的配置文件覆盖
|
||||
|
||||
## 环境变量
|
||||
|
||||
- `TZ`: 时区设置(默认:Asia/Shanghai)
|
||||
@ -141,26 +185,118 @@ services:
|
||||
- PHP-FPM 错误日志:`/var/log/php-fpm/www-error.log`
|
||||
- PHP-FPM 慢日志:`/var/log/php-fpm/slow.log`
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 开发环境设置
|
||||
|
||||
```bash
|
||||
# 1. 克隆或创建项目
|
||||
mkdir my-web-project && cd my-web-project
|
||||
|
||||
# 2. 复制Docker配置
|
||||
cp /path/to/common-nginx-fpm/* .
|
||||
|
||||
# 3. 设置环境变量
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件设置开发环境配置
|
||||
|
||||
# 4. 创建代码目录
|
||||
mkdir -p src
|
||||
|
||||
# 5. 启动开发环境
|
||||
docker-compose up -d web mysql redis
|
||||
|
||||
# 6. 访问应用
|
||||
open http://localhost
|
||||
```
|
||||
|
||||
### 生产环境部署
|
||||
|
||||
```bash
|
||||
# 1. 设置生产环境变量
|
||||
cat > .env << EOF
|
||||
PROJECT_NAME=prod-webapp
|
||||
WEB_PORT=80
|
||||
CODE_MOUNT_MODE=ro
|
||||
READ_ONLY=true
|
||||
MEMORY_LIMIT=512M
|
||||
CPU_LIMIT=1.0
|
||||
MYSQL_PASSWORD=your_very_strong_password
|
||||
EOF
|
||||
|
||||
# 2. 启动生产环境
|
||||
docker-compose up -d
|
||||
|
||||
# 3. 验证部署
|
||||
curl http://localhost/health
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
**1. 容器启动失败**
|
||||
```bash
|
||||
# 查看容器状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看启动日志
|
||||
docker-compose logs web
|
||||
```
|
||||
|
||||
**2. PHP文件不执行,显示源码**
|
||||
```bash
|
||||
# 检查nginx配置
|
||||
docker exec <container> nginx -t
|
||||
|
||||
# 检查PHP-FPM状态
|
||||
docker exec <container> php-fpm -t
|
||||
```
|
||||
|
||||
**3. 端口重定向问题**
|
||||
```bash
|
||||
# 测试重定向功能
|
||||
./tools/test-redirect.sh 8080
|
||||
|
||||
# 检查nginx重定向配置
|
||||
docker exec <container> nginx -T | grep -E "(port_in_redirect|server_name_in_redirect)"
|
||||
```
|
||||
|
||||
### 查看日志
|
||||
|
||||
```bash
|
||||
# 查看容器日志
|
||||
docker logs <container_id>
|
||||
# Docker Compose日志
|
||||
docker-compose logs -f web
|
||||
docker-compose logs -f mysql
|
||||
|
||||
# 进入容器查看详细日志
|
||||
docker exec -it <container_id> bash
|
||||
tail -f /var/log/nginx/error.log
|
||||
tail -f /var/log/php-fpm/www-error.log
|
||||
# 容器内日志
|
||||
docker exec <container> tail -f /var/log/nginx/error.log
|
||||
docker exec <container> tail -f /var/log/php-fpm/www-error.log
|
||||
```
|
||||
|
||||
### 测试配置
|
||||
### 配置测试
|
||||
|
||||
```bash
|
||||
# 测试 Nginx 配置
|
||||
docker exec <container_id> nginx -t
|
||||
docker exec <container> nginx -t
|
||||
|
||||
# 测试 PHP-FPM 配置
|
||||
docker exec <container_id> php-fpm -t
|
||||
docker exec <container> php-fpm -t
|
||||
|
||||
# 测试 PHP 扩展
|
||||
docker exec <container> php -m
|
||||
```
|
||||
|
||||
### 性能调优
|
||||
|
||||
```bash
|
||||
# 查看资源使用
|
||||
docker stats
|
||||
|
||||
# 调整PHP-FPM进程数
|
||||
# 编辑 config/www.conf
|
||||
pm.max_children = 50
|
||||
pm.start_servers = 5
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 35
|
||||
```
|
||||
|
||||
@ -29,6 +29,10 @@ http {
|
||||
types_hash_max_size 2048;
|
||||
client_max_body_size 100M;
|
||||
|
||||
# 重定向设置 - 解决端口映射问题
|
||||
port_in_redirect off;
|
||||
server_name_in_redirect off;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
@ -52,6 +56,10 @@ http {
|
||||
root /var/www/html;
|
||||
index index.php index.html index.htm;
|
||||
|
||||
# 支持反向代理头 (用于负载均衡器/反向代理场景)
|
||||
real_ip_header X-Forwarded-For;
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
|
||||
# 安全头
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
36
docker-compose.yaml
Normal file
36
docker-compose.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
image: common-nginx-fpm-alpine:latest
|
||||
container_name: ${PROJECT_NAME:-nginx-fpm-app}
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${WEB_PORT:-80}:80"
|
||||
volumes:
|
||||
# 代码目录
|
||||
- ${CODE_PATH:-./src}:/var/www/html
|
||||
# 自定义配置文件 (可选,取消注释以启用)
|
||||
# - ${NGINX_CONFIG:-./config/nginx.conf}:/etc/nginx/nginx.conf:ro
|
||||
# - ${PHP_CONFIG:-./config/php.ini}:/usr/local/etc/php/conf.d/custom.ini:ro
|
||||
# - ${FPM_CONFIG:-./config/www.conf}:/usr/local/etc/php-fpm.d/custom.conf:ro
|
||||
# 日志目录 (可选)
|
||||
# - ${LOG_PATH:-./logs}:/var/log
|
||||
environment:
|
||||
- TZ=${TIMEZONE:-Asia/Shanghai}
|
||||
# 安全配置 (生产环境推荐,取消注释以启用)
|
||||
# read_only: true
|
||||
# tmpfs:
|
||||
# - /tmp
|
||||
# - /var/run
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: ${MEMORY_LIMIT:-512M}
|
||||
cpus: '${CPU_LIMIT:-1.0}'
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
187
src/index.php
Normal file
187
src/index.php
Normal file
@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* 示例PHP应用
|
||||
* 展示nginx+php-fpm镜像的功能
|
||||
*/
|
||||
|
||||
// 设置错误报告
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// 获取请求信息
|
||||
$requestUri = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Nginx + PHP-FPM 示例应用</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: #333;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
.header {
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 30px;
|
||||
}
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.info-card {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #3498db;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.info-card h3 {
|
||||
margin-top: 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
.status {
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.status.success { background: #d4edda; color: #155724; }
|
||||
.status.info { background: #d1ecf1; color: #0c5460; }
|
||||
.footer {
|
||||
background: #ecf0f1;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
pre {
|
||||
background: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🚀 Nginx + PHP-FPM Docker 镜像</h1>
|
||||
<p>通用Web服务器环境 - 运行正常</p>
|
||||
<span class="status success">✅ 服务正常</span>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="info-grid">
|
||||
<div class="info-card">
|
||||
<h3>🐘 PHP 信息</h3>
|
||||
<p><strong>版本:</strong> <?php echo PHP_VERSION; ?></p>
|
||||
<p><strong>SAPI:</strong> <?php echo php_sapi_name(); ?></p>
|
||||
<p><strong>内存限制:</strong> <?php echo ini_get('memory_limit'); ?></p>
|
||||
<p><strong>上传限制:</strong> <?php echo ini_get('upload_max_filesize'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="info-card">
|
||||
<h3>🌐 服务器信息</h3>
|
||||
<p><strong>服务器软件:</strong> <?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'; ?></p>
|
||||
<p><strong>请求方法:</strong> <?php echo $method; ?></p>
|
||||
<p><strong>请求URI:</strong> <?php echo htmlspecialchars($requestUri); ?></p>
|
||||
<p><strong>服务器时间:</strong> <?php echo date('Y-m-d H:i:s'); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="info-card">
|
||||
<h3>🔧 已安装扩展</h3>
|
||||
<?php
|
||||
$extensions = ['pdo_mysql', 'pdo_pgsql', 'pgsql', 'mysqli', 'opcache', 'curl', 'json', 'mbstring'];
|
||||
foreach ($extensions as $ext) {
|
||||
$status = extension_loaded($ext) ? 'success' : 'info';
|
||||
$icon = extension_loaded($ext) ? '✅' : '❌';
|
||||
echo "<span class='status $status'>$icon $ext</span> ";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="info-card">
|
||||
<h3>📊 系统状态</h3>
|
||||
<p><strong>负载:</strong> <?php echo sys_getloadavg()[0] ?? 'N/A'; ?></p>
|
||||
<p><strong>内存使用:</strong> <?php echo round(memory_get_usage(true) / 1024 / 1024, 2); ?> MB</p>
|
||||
<p><strong>峰值内存:</strong> <?php echo round(memory_get_peak_usage(true) / 1024 / 1024, 2); ?> MB</p>
|
||||
<p><strong>时区:</strong> <?php echo date_default_timezone_get(); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-card">
|
||||
<h3>🔗 数据库连接测试</h3>
|
||||
<?php
|
||||
// MySQL连接测试
|
||||
echo "<h4>MySQL:</h4>";
|
||||
try {
|
||||
$mysql_host = getenv('MYSQL_HOST') ?: 'mysql';
|
||||
$mysql_db = getenv('MYSQL_DATABASE') ?: 'webapp';
|
||||
$mysql_user = getenv('MYSQL_USER') ?: 'webapp';
|
||||
$mysql_pass = getenv('MYSQL_PASSWORD') ?: 'password';
|
||||
|
||||
$pdo = new PDO("mysql:host=$mysql_host;dbname=$mysql_db", $mysql_user, $mysql_pass);
|
||||
echo "<span class='status success'>✅ MySQL连接成功</span>";
|
||||
} catch (Exception $e) {
|
||||
echo "<span class='status info'>ℹ️ MySQL未配置或连接失败</span>";
|
||||
}
|
||||
|
||||
// PostgreSQL连接测试
|
||||
echo "<h4>PostgreSQL:</h4>";
|
||||
try {
|
||||
$pg_host = getenv('POSTGRES_HOST') ?: 'postgres';
|
||||
$pg_db = getenv('POSTGRES_DB') ?: 'webapp';
|
||||
$pg_user = getenv('POSTGRES_USER') ?: 'webapp';
|
||||
$pg_pass = getenv('POSTGRES_PASSWORD') ?: 'password';
|
||||
|
||||
$pdo = new PDO("pgsql:host=$pg_host;dbname=$pg_db", $pg_user, $pg_pass);
|
||||
echo "<span class='status success'>✅ PostgreSQL连接成功</span>";
|
||||
} catch (Exception $e) {
|
||||
echo "<span class='status info'>ℹ️ PostgreSQL未配置或连接失败</span>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="info-card">
|
||||
<h3>📝 环境变量</h3>
|
||||
<pre><?php
|
||||
$env_vars = ['TZ', 'PHP_INI_DIR', 'PHP_CFLAGS', 'PHP_VERSION'];
|
||||
foreach ($env_vars as $var) {
|
||||
$value = getenv($var) ?: 'Not set';
|
||||
echo "$var: $value\n";
|
||||
}
|
||||
?></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>🐳 Common Nginx + PHP-FPM Docker Image</p>
|
||||
<p>访问 <a href="/health">/health</a> 进行健康检查</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
187
start.sh
Executable file
187
start.sh
Executable file
@ -0,0 +1,187 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Common Nginx + PHP-FPM Docker 快速启动脚本
|
||||
# 使用方法: ./start.sh [dev|prod|stop|logs|status]
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 项目名称
|
||||
PROJECT_NAME="common-nginx-fpm"
|
||||
|
||||
# 打印带颜色的消息
|
||||
print_message() {
|
||||
local color=$1
|
||||
local message=$2
|
||||
echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] ${message}${NC}"
|
||||
}
|
||||
|
||||
# 检查Docker和Docker Compose
|
||||
check_requirements() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_message $RED "错误: Docker 未安装或未在PATH中"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
print_message $RED "错误: Docker Compose 未安装或未在PATH中"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建必要的目录
|
||||
create_directories() {
|
||||
print_message $BLUE "创建必要的目录..."
|
||||
mkdir -p src logs config/mysql config/postgres
|
||||
|
||||
# 如果src目录为空,创建示例文件
|
||||
if [ ! -f "src/index.php" ]; then
|
||||
print_message $YELLOW "创建示例 index.php 文件..."
|
||||
# index.php 已经存在,这里不需要重复创建
|
||||
fi
|
||||
}
|
||||
|
||||
# 设置环境变量
|
||||
setup_env() {
|
||||
local env_type=$1
|
||||
|
||||
if [ ! -f ".env" ]; then
|
||||
print_message $BLUE "复制环境变量文件..."
|
||||
cp .env.example .env
|
||||
fi
|
||||
|
||||
case $env_type in
|
||||
"dev")
|
||||
print_message $BLUE "配置开发环境..."
|
||||
sed -i.bak 's/PROJECT_NAME=.*/PROJECT_NAME=dev-webapp/' .env
|
||||
sed -i.bak 's/WEB_PORT=.*/WEB_PORT=8000/' .env
|
||||
sed -i.bak 's/CODE_MOUNT_MODE=.*/CODE_MOUNT_MODE=rw/' .env
|
||||
sed -i.bak 's/READ_ONLY=.*/READ_ONLY=false/' .env
|
||||
sed -i.bak 's/MEMORY_LIMIT=.*/MEMORY_LIMIT=1G/' .env
|
||||
sed -i.bak 's/CPU_LIMIT=.*/CPU_LIMIT=2.0/' .env
|
||||
rm -f .env.bak
|
||||
;;
|
||||
"prod")
|
||||
print_message $BLUE "配置生产环境..."
|
||||
sed -i.bak 's/PROJECT_NAME=.*/PROJECT_NAME=prod-webapp/' .env
|
||||
sed -i.bak 's/WEB_PORT=.*/WEB_PORT=80/' .env
|
||||
sed -i.bak 's/CODE_MOUNT_MODE=.*/CODE_MOUNT_MODE=ro/' .env
|
||||
sed -i.bak 's/READ_ONLY=.*/READ_ONLY=true/' .env
|
||||
sed -i.bak 's/MEMORY_LIMIT=.*/MEMORY_LIMIT=512M/' .env
|
||||
sed -i.bak 's/CPU_LIMIT=.*/CPU_LIMIT=1.0/' .env
|
||||
rm -f .env.bak
|
||||
|
||||
print_message $YELLOW "请确保已设置强密码!"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 启动服务
|
||||
start_services() {
|
||||
local env_type=$1
|
||||
|
||||
print_message $BLUE "构建镜像..."
|
||||
docker-compose build
|
||||
|
||||
case $env_type in
|
||||
"dev")
|
||||
print_message $GREEN "启动开发环境..."
|
||||
docker-compose up -d
|
||||
;;
|
||||
"prod")
|
||||
print_message $GREEN "启动生产环境..."
|
||||
docker-compose up -d
|
||||
;;
|
||||
esac
|
||||
|
||||
# 等待服务启动
|
||||
print_message $BLUE "等待服务启动..."
|
||||
sleep 10
|
||||
|
||||
# 健康检查
|
||||
local port=$(grep WEB_PORT .env | cut -d'=' -f2)
|
||||
if curl -s "http://localhost:${port}/health" > /dev/null; then
|
||||
print_message $GREEN "✅ 服务启动成功!"
|
||||
print_message $GREEN "🌐 访问地址: http://localhost:${port}"
|
||||
|
||||
|
||||
else
|
||||
print_message $RED "❌ 服务启动失败,请检查日志"
|
||||
docker-compose logs web
|
||||
fi
|
||||
}
|
||||
|
||||
# 停止服务
|
||||
stop_services() {
|
||||
print_message $YELLOW "停止所有服务..."
|
||||
docker-compose down
|
||||
print_message $GREEN "✅ 服务已停止"
|
||||
}
|
||||
|
||||
# 查看日志
|
||||
show_logs() {
|
||||
print_message $BLUE "显示服务日志..."
|
||||
docker-compose logs -f --tail=100
|
||||
}
|
||||
|
||||
# 查看状态
|
||||
show_status() {
|
||||
print_message $BLUE "服务状态:"
|
||||
docker-compose ps
|
||||
|
||||
print_message $BLUE "资源使用:"
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
|
||||
}
|
||||
|
||||
# 显示帮助
|
||||
show_help() {
|
||||
echo "Common Nginx + PHP-FPM Docker 快速启动脚本"
|
||||
echo ""
|
||||
echo "使用方法:"
|
||||
echo " $0 dev - 启动开发环境 (端口8000)"
|
||||
echo " $0 prod - 启动生产环境 (端口80)"
|
||||
echo " $0 stop - 停止所有服务"
|
||||
echo " $0 logs - 查看服务日志"
|
||||
echo " $0 status - 查看服务状态"
|
||||
echo " $0 help - 显示此帮助信息"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 dev # 启动开发环境"
|
||||
echo " $0 prod # 启动生产环境"
|
||||
echo " $0 logs # 查看日志"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
local command=${1:-help}
|
||||
|
||||
case $command in
|
||||
"dev"|"prod")
|
||||
check_requirements
|
||||
create_directories
|
||||
setup_env $command
|
||||
start_services $command
|
||||
;;
|
||||
"stop")
|
||||
stop_services
|
||||
;;
|
||||
"logs")
|
||||
show_logs
|
||||
;;
|
||||
"status")
|
||||
show_status
|
||||
;;
|
||||
"help"|*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
114
tools/test-extensions.sh
Executable file
114
tools/test-extensions.sh
Executable file
@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 测试PHP扩展安装脚本
|
||||
echo "🔍 测试PHP扩展安装..."
|
||||
|
||||
# 构建镜像
|
||||
echo "📦 构建Docker镜像..."
|
||||
docker build -t common-nginx-fpm:test . || {
|
||||
echo "❌ 镜像构建失败"
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "✅ 镜像构建成功"
|
||||
|
||||
# 运行容器并测试扩展
|
||||
echo "🧪 测试PHP扩展..."
|
||||
docker run --rm common-nginx-fpm:test php -m > /tmp/php_modules.txt
|
||||
|
||||
echo "📋 已安装的PHP扩展:"
|
||||
cat /tmp/php_modules.txt
|
||||
|
||||
echo ""
|
||||
echo "🔍 检查关键扩展:"
|
||||
|
||||
# 检查关键扩展
|
||||
extensions=(
|
||||
"bcmath"
|
||||
"bz2"
|
||||
"curl"
|
||||
"dom"
|
||||
"exif"
|
||||
"fileinfo"
|
||||
"ftp"
|
||||
"gd"
|
||||
"gettext"
|
||||
"iconv"
|
||||
"ldap"
|
||||
"mbstring"
|
||||
"mysqli"
|
||||
"opcache"
|
||||
"pcntl"
|
||||
"pdo"
|
||||
"pdo_mysql"
|
||||
"pdo_pgsql"
|
||||
"pdo_sqlite"
|
||||
"pgsql"
|
||||
"posix"
|
||||
"redis"
|
||||
"shmop"
|
||||
"simplexml"
|
||||
"soap"
|
||||
"sockets"
|
||||
"sqlite3"
|
||||
"xml"
|
||||
"xmlreader"
|
||||
"xmlwriter"
|
||||
"xsl"
|
||||
"zip"
|
||||
)
|
||||
|
||||
missing_extensions=()
|
||||
|
||||
for ext in "${extensions[@]}"; do
|
||||
# 特殊处理一些扩展名称的变体
|
||||
case $ext in
|
||||
"opcache")
|
||||
if grep -q "^Zend OPcache$" /tmp/php_modules.txt; then
|
||||
echo "✅ $ext"
|
||||
else
|
||||
echo "❌ $ext (缺失)"
|
||||
missing_extensions+=("$ext")
|
||||
fi
|
||||
;;
|
||||
"pdo")
|
||||
if grep -q "^PDO$" /tmp/php_modules.txt; then
|
||||
echo "✅ $ext"
|
||||
else
|
||||
echo "❌ $ext (缺失)"
|
||||
missing_extensions+=("$ext")
|
||||
fi
|
||||
;;
|
||||
"simplexml")
|
||||
if grep -q "^SimpleXML$" /tmp/php_modules.txt; then
|
||||
echo "✅ $ext"
|
||||
else
|
||||
echo "❌ $ext (缺失)"
|
||||
missing_extensions+=("$ext")
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if grep -q "^$ext$" /tmp/php_modules.txt; then
|
||||
echo "✅ $ext"
|
||||
else
|
||||
echo "❌ $ext (缺失)"
|
||||
missing_extensions+=("$ext")
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ${#missing_extensions[@]} -eq 0 ]; then
|
||||
echo ""
|
||||
echo "🎉 所有扩展安装成功!"
|
||||
else
|
||||
echo ""
|
||||
echo "⚠️ 缺失的扩展: ${missing_extensions[*]}"
|
||||
fi
|
||||
|
||||
# 清理临时文件
|
||||
rm -f /tmp/php_modules.txt
|
||||
|
||||
echo ""
|
||||
echo "📊 镜像信息:"
|
||||
docker images common-nginx-fpm:test --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}"
|
||||
145
tools/test-redirect.sh
Executable file
145
tools/test-redirect.sh
Executable file
@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 测试nginx重定向是否正确处理端口号
|
||||
# 使用方法: ./test-redirect.sh [port]
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 默认端口
|
||||
PORT=${1:-8080}
|
||||
CONTAINER_NAME="test-redirect-nginx-fpm"
|
||||
|
||||
print_message() {
|
||||
local color=$1
|
||||
local message=$2
|
||||
echo -e "${color}[$(date '+%H:%M:%S')] ${message}${NC}"
|
||||
}
|
||||
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
print_message $YELLOW "清理测试环境..."
|
||||
docker stop $CONTAINER_NAME 2>/dev/null || true
|
||||
docker rm $CONTAINER_NAME 2>/dev/null || true
|
||||
}
|
||||
|
||||
# 设置清理陷阱
|
||||
trap cleanup EXIT
|
||||
|
||||
print_message $BLUE "开始测试nginx重定向功能 (端口: $PORT)"
|
||||
|
||||
# 构建镜像
|
||||
print_message $BLUE "构建测试镜像..."
|
||||
docker build -t common-nginx-fpm-alpine . > /dev/null
|
||||
|
||||
# 启动容器
|
||||
print_message $BLUE "启动测试容器..."
|
||||
docker run -d \
|
||||
--name $CONTAINER_NAME \
|
||||
-p $PORT:80 \
|
||||
-v $(pwd)/src:/var/www/html \
|
||||
common-nginx-fpm-alpine > /dev/null
|
||||
|
||||
# 等待容器启动
|
||||
print_message $BLUE "等待服务启动..."
|
||||
sleep 5
|
||||
|
||||
# 创建测试目录和文件
|
||||
print_message $BLUE "创建测试文件..."
|
||||
mkdir -p src/test
|
||||
cat > src/test/redirect.php << 'EOF'
|
||||
<?php
|
||||
// 测试重定向
|
||||
if (!isset($_GET['redirected'])) {
|
||||
// 执行重定向
|
||||
header("Location: /test/redirect.php?redirected=1");
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "重定向测试成功!";
|
||||
echo "<br>当前URL: " . $_SERVER['REQUEST_URI'];
|
||||
echo "<br>服务器端口: " . $_SERVER['SERVER_PORT'];
|
||||
echo "<br>HTTP_HOST: " . $_SERVER['HTTP_HOST'];
|
||||
?>
|
||||
EOF
|
||||
|
||||
# 测试健康检查
|
||||
print_message $BLUE "测试健康检查..."
|
||||
if curl -s "http://localhost:$PORT/health" > /dev/null; then
|
||||
print_message $GREEN "✅ 健康检查通过"
|
||||
else
|
||||
print_message $RED "❌ 健康检查失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 测试基本访问
|
||||
print_message $BLUE "测试基本访问..."
|
||||
if curl -s "http://localhost:$PORT/" | grep -q "PHP"; then
|
||||
print_message $GREEN "✅ 基本访问正常"
|
||||
else
|
||||
print_message $RED "❌ 基本访问失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 测试重定向
|
||||
print_message $BLUE "测试重定向功能..."
|
||||
REDIRECT_RESPONSE=$(curl -s -I "http://localhost:$PORT/test/redirect.php")
|
||||
|
||||
if echo "$REDIRECT_RESPONSE" | grep -q "HTTP/1.1 302"; then
|
||||
LOCATION=$(echo "$REDIRECT_RESPONSE" | grep -i "location:" | tr -d '\r')
|
||||
print_message $GREEN "✅ 重定向响应正常"
|
||||
print_message $BLUE "重定向位置: $LOCATION"
|
||||
|
||||
# 检查重定向URL是否包含错误的端口号
|
||||
if echo "$LOCATION" | grep -q ":80"; then
|
||||
print_message $RED "❌ 重定向URL包含内部端口号 :80"
|
||||
print_message $RED "这可能导致外部访问问题"
|
||||
else
|
||||
print_message $GREEN "✅ 重定向URL不包含内部端口号"
|
||||
fi
|
||||
|
||||
# 测试跟随重定向
|
||||
FINAL_RESPONSE=$(curl -s -L "http://localhost:$PORT/test/redirect.php")
|
||||
if echo "$FINAL_RESPONSE" | grep -q "重定向测试成功"; then
|
||||
print_message $GREEN "✅ 重定向跟随成功"
|
||||
else
|
||||
print_message $RED "❌ 重定向跟随失败"
|
||||
fi
|
||||
else
|
||||
print_message $RED "❌ 重定向测试失败"
|
||||
fi
|
||||
|
||||
# 测试目录重定向 (trailing slash)
|
||||
print_message $BLUE "测试目录重定向..."
|
||||
mkdir -p src/testdir
|
||||
echo "目录测试" > src/testdir/index.html
|
||||
|
||||
DIR_REDIRECT=$(curl -s -I "http://localhost:$PORT/testdir")
|
||||
if echo "$DIR_REDIRECT" | grep -q "HTTP/1.1 301"; then
|
||||
LOCATION=$(echo "$DIR_REDIRECT" | grep -i "location:" | tr -d '\r')
|
||||
print_message $GREEN "✅ 目录重定向正常"
|
||||
print_message $BLUE "重定向位置: $LOCATION"
|
||||
|
||||
if echo "$LOCATION" | grep -q ":80"; then
|
||||
print_message $RED "❌ 目录重定向包含内部端口号"
|
||||
else
|
||||
print_message $GREEN "✅ 目录重定向不包含内部端口号"
|
||||
fi
|
||||
else
|
||||
print_message $YELLOW "⚠️ 目录重定向未触发 (可能已正确配置)"
|
||||
fi
|
||||
|
||||
# 显示nginx配置相关信息
|
||||
print_message $BLUE "检查nginx配置..."
|
||||
docker exec $CONTAINER_NAME nginx -T 2>/dev/null | grep -E "(port_in_redirect|server_name_in_redirect)" || print_message $YELLOW "未找到重定向配置"
|
||||
|
||||
print_message $GREEN "🎉 重定向测试完成!"
|
||||
|
||||
# 清理测试文件
|
||||
rm -rf src/test src/testdir
|
||||
Loading…
x
Reference in New Issue
Block a user