用 Docker 运行网站服务

Nginx

Nginx 是一款功能强大的开源反向代理服务器,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。同时,它还可以作为负载均衡器、HTTP 缓存或 Web 服务器。

下载

可以放心使用官方最新版本镜像,不同版本没有兼容性问题:

[root@server4 ~]$ docker search --filter=is-official=true nginx
NAME      DESCRIPTION                STARS     OFFICIAL   AUTOMATED
nginx     Official build of Nginx.   15698     [OK]       
[root@server4 ~]$ docker pull nginx

Nginx 服务中主要使用的目录如下:

路径 说明
/usr/share/nginx/html/ 网页数据存放处。
/etc/nginx/ 配置文件目录。
/var/log/nginx/ 日志存放目录。

Nginx 作为 Web 服务使用的端口如下:

端口 说明
80 HTTP 端口
443 HTTPS 端口

配置

启动一个临时的 Nginx 容器,将要挂载的目录复制出来:

[root@server4 ~]$ docker run -d --name tempn nginx
fb67cb1fce9f32b57729cb62c2a5d716edc1d42d39fcd1faae1bc57f6bab6a9d
[root@server4 ~]$ docker cp tempn:/etc/nginx/ ~/nginx/config
[root@server4 ~]$ docker rm -f tempn

Nginx 主配置文件 nginx.conf 参考如下:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    use epoll;
    accept_mutex on;
    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"';

    access_log  /var/log/nginx/access.log  main;
    
    #上传文件相关参数
    client_max_body_size 200M;
    client_body_buffer_size 1024K;
    client_header_timeout    1m;
    client_body_timeout      1m;
    proxy_connect_timeout     60s;
    proxy_read_timeout      1m;
    proxy_send_timeout      1m;

    #gzip压缩参数
    gzip  on;                 # 开启gzip功能
    gzip_min_length  1k;      # 响应页数据上限
    gzip_buffers     4 16k;   # 缓存空间大小
    gzip_comp_level 6;        # 设置压缩级别为6
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json; # 压缩文件类型
    gzip_disable "MSIE [1-6]\."; # IE 1-6关闭gzip压缩
    gzip_vary on;             # 启用压缩标识


    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;
    #在一次长连接上所允许请求的资源的最大数量
    keepalive_requests 5;

    set_real_ip_from   0.0.0.0/0;
    real_ip_header     X-Forwarded-For;
    real_ip_recursive on;
    
    include /etc/nginx/conf.d/*.conf;
}

个性化主机配置文件一般放在 config/conf.d 目录中。例如,本站配置文件 blog.x2b.net.conf 内容如下:

server {
    listen 80;
    listen 443 ssl;
    server_name blog.x2b.net;

    ssl_certificate   /etc/nginx/certs/x2b.net.pem;
    ssl_certificate_key  /etc/nginx/certs/x2b.net.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1.2 TLSv1.3 SSLv3;
    ssl_prefer_server_ciphers on;
    location / {
        root   /usr/share/nginx/html/x2b.net-deploy/;
        index  index.html index.htm;
    }
}

x2b.net 的 SSL 证书上传到服务器,并修改权限为只读:

[root@server4 ~]$ useradd nginx
[root@server4 ~]$ chown -R nginx:nginx cert
[root@server4 ~]$ chmod -R 400 cert

启动

修改好配置文件后,挂载目录和映射端口启动:

[root@server4 ~]$ docker run -d --name nginx -p 80:80 -p 443:443 -v /docker/nginx/html:/usr/share/nginx/html:ro -v /docker/nginx/conf.d:/etc/nginx/conf.d:ro nginx
220f821e4fed6e1cc421509bbfbaf6b36a71739b69c89c14d929a34e27ab0524
[root@server4 ~]$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                                      NAMES
220f821e4fed   nginx          "/docker-entrypoint.…"   21 seconds ago   Up 19 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   nginx

使用 Docker Compose 启动配置文件内容参考:

version: '2'

services:
  nginx:
    image: nginx:1.23.4
    container_name: nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./config:/etc/nginx
      - ./html:/usr/share/nginx/html
      - ./logs:/var/log/nginx
      - ./certs:/etc/nginx/certs
    environment:
      - TZ=Asia/Shanghai
      - NGINX_WORKER_PROCESSES=auto
      - NGINX_HTTP_KEEPALIVE_TIMEOUT=65

这里额外挂载了配置文件中指定的日志目录,因为有时需要对 Nginx 日志做分析。

隧道

本地环境可以配合 cloudflared 隧道来发布网站。使用 Docker Compose 启动配置参考:

version: '3.9'

services:
  cloudflare:
    image: cloudflare/cloudflared:2023.4.0
    container_name: cloudflared
    restart: always
    network_mode: "host"
    volumes:
      - ./certs/cert.pem:/home/nonroot/.cloudflared/cert.pem
    command: tunnel run --token "eyJhIjoiZWEyZjE2MTE4NjkyMzFlYmYzMWZjNDI0Zj1"

网络模式必须为 host 才可正常连接服务器。

WordPress

WordPress 是基于 PHP 和 MySQL 构建的一款开源内容管理系统 (CMS),用于创建和管理网站、博客和应用程序。

下载

WordPress 服务中主要使用的目录如下:

路径 说明
/var/www/html/ 网页数据存放处。
/etc/apache2/ Apache 配置文件目录。
/usr/local/etc/php/conf.d/ PHP 配置文件目录。

WordPress 默认使用的端口如下:

端口 说明
80 HTTP 端口

配置

由于 WordPress 配置文件太多,因此最好只挂载需要修改的文件,否则在升级 WordPress 版本后可能会出兼容性问题。

修改上传限制

修改默认文件上传限制,配置文件 uploads.ini 内容如下:

file_uploads = On
memory_limit = 300M
post_max_size = 200M
upload_max_filesize = 100M
max_execution_time = 600

获取访客真实地址

添加 remoteip.confremoteip.load 配置文件用于获取用户真实 IP 地址:

RemoteIPHeader HTTP-X-Forwarded-For
RemoteIPProxiesHeader X-Forwarded-By

载入模块配置:

LoadModule remoteip_module /usr/lib/apache2/modules/mod_remoteip.so

Nginx 配置

在 Nginx 上新增配置文件 wordpress.x2b.net.conf ,参考内容如下:

server {
    listen 80;
    listen 443 ssl;
    server_name wordpress.x2b.net;

    ssl_certificate   /etc/nginx/certs/x2b.net.pem;
    ssl_certificate_key  /etc/nginx/certs/x2b.net.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1.2 TLSv1.3 SSLv3;

    ssl_prefer_server_ciphers off;
    ssl_stapling on;
    ssl_stapling_verify on;

    location / {
        proxy_pass http://192.168.2.204:8080;
        proxy_redirect default;
        proxy_read_timeout 86400;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # 保证获取到真实IP
        proxy_set_header X-Real-IP $remote_addr;
        # 真实端口号
        proxy_set_header X-Real-Port $remote_port;
        # X-Forwarded-For 是一个 HTTP 扩展头部。
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 在多级代理的情况下,记录每次代理之前的客户端真实ip
        proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
        # 获取到真实协议
        proxy_set_header X-Forwarded-Proto $scheme;
        # 真实主机名
        proxy_set_header Host $host;
        # 设置变量
        proxy_set_header X-NginX-Proxy true;

    }
}

主要是加入获取访客真实 IP 地址的相关配置。

启动

使用 Docker Compose 启动配置文件参考:

version: '3.9'

services:
  wordpress:
    image: wordpress:6.2.0
    container_name: wordpress
    restart: always
    ports:
      - "8080:80"
    environment:
      - WORDPRESS_DB_HOST=192.168.2.204
      - WORDPRESS_DB_USER=root
      - WORDPRESS_DB_PASSWORD=root密码
      - WORDPRESS_DB_NAME=wordpress
      - TZ=Asia/Shanghai
    volumes:
      - ./html:/var/www/html
      - ./config/remoteip.conf:/etc/apache2/mods-enabled/remoteip.conf
      - ./config/remoteip.load:/etc/apache2/mods-enabled/remoteip.load
      - ./config/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini

Tinyproxy

Tinyproxy 是一个轻量级的开源代理服务器,旨在提供快速、高效的代理服务。它主要用于在本地网络中转发 HTTP 和 HTTPS 请求,以便用户可以通过代理服务器访问互联网资源。

用 Docker Compose 启动的配置文件参考如下:

version: '3.9'

services:
  tinyproxy:
    image: monokal/tinyproxy:latest
    container_name: tinyproxy
    restart: always
    network_mode: "host"
    command: /bin/bash /opt/docker-tinyproxy/run.sh ANY

由于使用属主机网络,所以不需要配置端口。默认配置中对外监听的代理端口号为 8888。

FRP

frp(Fast Reverse Proxy)是一个快速、现代化的反向代理工具。通过使用 frp 可以方便地将内网服务暴露给外部网络,实现远程访问内网服务的需求。

服务端 frps 配置文件 config/frps.ini 极简化配置内容参考如下:

[common]
bind_addr = 0.0.0.0
bind_port = 7000
bind_udp_port = 7001
kcp_bind_port = 7000
dashboard_addr = 0.0.0.0
dashboard_port = 7002
dashboard_user = hxz393
dashboard_pwd = nopasswd
log_file = ./logs/frps.log
log_level = info
log_max_days = 3
token = #Zu1RY#uc@z::z.HA<N{^4F
max_pool_count = 10
max_ports_per_client = 0
tcp_mux = true

用 Docker Compose 启动 frp 服务器端的配置文件参考如下:

version: '2'

services:
  nginx:
    image: snowdreamtech/frps:0.48.0
    container_name: frps
    restart: always
    ports:
      - "7000:7000"
      - "7001:7001"
      - "7002:7002"
      - "10101:10101"
      - "10102:10102"
    volumes:
      - ./config/:/etc/frp/
      - ./logs/:/logs/

其中 10101 和 10102 端口为预留给客户端连接的端口。