我来为您介绍如何使用 Docker Compose 安装和配置 Nginx,包括基础部署、常用配置和进阶场景。

一、基础配置

1. 最简单的 Nginx 部署

创建 `docker-compose.yml`:

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/usr/share/nginx/html
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    restart: unless-stopped
```

目录结构:

```
project/
├── docker-compose.yml
├── nginx.conf
└── html/
    └── index.html
```

2. 启动命令

```bash
# 启动
docker-compose up -d

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs -f nginx

# 停止
docker-compose down

# 重启
docker-compose restart nginx
```

二、常用配置模板

2.1 反向代理配置

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./ssl:/etc/nginx/ssl:ro
      - ./logs:/var/log/nginx
    depends_on:
      - app1
      - app2
    networks:
      - frontend
      - backend
    restart: always

  # 后端应用示例
  app1:
    image: httpd:alpine
    container_name: web1
    networks:
      - backend

  app2:
    image: httpd:alpine
    container_name: web2
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
```

`nginx.conf` 配置:

```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # 日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 100M;

    # Gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;

    # 包含其他配置
    include /etc/nginx/conf.d/*.conf;
}
```

`conf.d/default.conf` 反向代理配置:

```nginx
server {
    listen 80;
    server_name localhost;
    
    # 静态文件
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ =404;
    }
    
    # 反向代理到 app1
    location /api1/ {
        proxy_pass http://app1:80/;
        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;
    }
    
    # 反向代理到 app2
    location /api2/ {
        proxy_pass http://app2:80/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    
    # 负载均衡示例
    location /load-balance/ {
        proxy_pass http://backend_servers;
    }
}

# 负载均衡 upstream
upstream backend_servers {
    server app1:80 weight=5;
    server app2:80 weight=5;
    keepalive 32;
}
```

三、HTTPS/SSL 配置

3.1 使用自签名证书

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
      - ./html:/usr/share/nginx/html
    restart: always
```

生成自签名证书:

```bash
mkdir ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ssl/nginx.key \
  -out ssl/nginx.crt \
  -subj "/C=CN/ST=State/L=City/O=Organization/CN=localhost"
```

SSL 配置文件 `conf.d/ssl.conf`:

```nginx
server {
    listen 443 ssl http2;
    server_name localhost;
    
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    
    # SSL 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name localhost;
    return 301 https://$server_name$request_uri;
}
```

3.2 使用 Let's Encrypt(自动续期)

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./certbot/conf:/etc/letsencrypt:ro
      - ./certbot/www:/var/www/certbot
      - ./html:/usr/share/nginx/html
    restart: always

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
```

初始化证书脚本 `init-letsencrypt.sh`:

```bash
#!/bin/bash

domains=(example.com www.example.com)
rsa_key_size=4096
data_path="./certbot"
email="your@email.com"

# 创建目录
mkdir -p $data_path/conf $data_path/www

# 获取证书
docker-compose run --rm --entrypoint "\
  certbot certonly --webroot -w /var/www/certbot \
    --register-unsafely-without-email \
    --agree-tos \
    --force-renewal \
    -d ${domains[0]} -d ${domains[1]}" certbot
```

四、多站点配置

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./sites:/etc/nginx/sites:ro
      - ./html/site1:/var/www/site1
      - ./html/site2:/var/www/site2
      - ./logs:/var/log/nginx
    restart: always
```

`nginx.conf`:

```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;
    
    # 包含所有站点配置
    include /etc/nginx/sites/*.conf;
}
```

`sites/site1.conf`:

```nginx
server {
    listen 80;
    server_name site1.com www.site1.com;
    root /var/www/site1;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
    
    location /api {
        proxy_pass http://backend:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

`sites/site2.conf`:

```nginx
server {
    listen 80;
    server_name site2.com www.site2.com;
    root /var/www/site2;
    index index.html;
    
    # 启用 Gzip
    gzip on;
    gzip_types text/css application/javascript;
    
    # 缓存静态资源
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}
```

五、与 PHP 集成(LNMP)

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./www:/var/www/html:ro
    depends_on:
      - php
    networks:
      - web

  php:
    image: php:8.1-fpm-alpine
    volumes:
      - ./www:/var/www/html
    networks:
      - web

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: userpass
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - web

volumes:
  mysql_data:

networks:
  web:
    driver: bridge
```

PHP-FPM 配置 `conf.d/php.conf`:

```nginx
server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```

六、生产环境优化配置

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./ssl:/etc/nginx/ssl:ro
      - ./html:/usr/share/nginx/html:ro
      - nginx_cache:/var/cache/nginx
      - ./logs:/var/log/nginx
    environment:
      - NGINX_HOST=example.com
      - NGINX_PORT=80
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  nginx_cache:
```

生产级 `nginx.conf`:

```nginx
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # 日志
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    '$request_time $upstream_response_time';
    
    access_log /var/log/nginx/access.log main buffer=32k flush=5s;
    
    # 性能优化
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 30;
    keepalive_requests 1000;
    reset_timedout_connection on;
    client_body_timeout 10;
    send_timeout 2;
    
    # 压缩
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 1000;
    gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
    
    # 限速和限流
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    
    # 缓存配置
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=1g;
    
    include /etc/nginx/conf.d/*.conf;
}
```

七、常用命令速查

```bash
# 启动
docker-compose up -d

# 查看日志
docker-compose logs -f nginx

# 进入容器
docker-compose exec nginx sh

# 测试配置
docker-compose exec nginx nginx -t

# 重载配置(不重启)
docker-compose exec nginx nginx -s reload

# 查看状态
docker-compose ps

# 停止并删除
docker-compose down -v

# 更新镜像
docker-compose pull && docker-compose up -d
```

需要我针对特定场景(如负载均衡、WebSocket 代理、Kubernetes 部署)提供更详细的配置吗?

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐