Docker 构建 nginx-redis-alpine 项目详解

Docker 构建 nginx-redis-alpine 项目详解

一、课程概述

嘿,朋友们!今天咱们要深入探索一个超级实用的项目 ------nginx-redis-alpine!这个项目可不简单,它包含了好多重要的知识点,像文件目录结构、核心文件的作用及配置、自签名证书的生成,还有镜像构建和容器运行等等。我保证,跟着我一步步走,你就能彻底搞懂这个项目的实现原理和各种应用场景,让你在 Docker 世界里更加游刃有余!

二、课程目标

  • 理解 nginx-redis-alpine 项目的整体架构和文件组织方式。
  • 掌握 Dockerfile 多阶段构建、Nginx 配置、启动脚本编写等关键技术。

三、课程内容

(一)文件目录结构

bash 复制代码
nginx-redis-alpine/
├── Dockerfile        # 构建镜像的魔法秘籍
├── nginx.conf        # Nginx 的核心配置文件
├── ssl               # SSL 证书的小窝
│   ├── cert.pem      # 证书文件
│   └── key.pem       # 密钥文件
└── start_nginx.sh    # 启动 Nginx 的启动脚本

1 directory, 5 files
  • Dockerfile:用于构建 Docker 镜像,包含了构建和运行阶段的指令。
  • nginx.conf:Nginx 的配置文件,定义了服务器的运行参数、虚拟主机、缓存配置等。
  • ssl 目录 :存放 SSL 证书文件,包括 cert.pem(证书文件)和 key.pem(密钥文件)。
  • start_nginx.sh:启动 Nginx 的脚本,负责检查环境变量、替换配置文件中的占位符、检查配置文件有效性等。

(二)核心文件详解

1. Dockerfile
dockerfile 复制代码
# 第一阶段:构建阶段
FROM alpine:latest AS builder

# 安装必要的依赖
RUN apk update && apk add --no-cache \
    build-base \
    pcre-dev \
    zlib-dev \
    openssl-dev \
    wget \
    unzip \
    git

# 下载Nginx 1.25源码
RUN wget http://nginx.org/download/nginx-1.25.0.tar.gz && \
    tar -zxvf nginx-1.25.0.tar.gz && \
    rm nginx-1.25.0.tar.gz

# 下载Redis插件源码
RUN git clone https://github.com/openresty/redis2-nginx-module.git && \
    cd redis2-nginx-module && \
    git checkout v0.15

# 编译并安装Nginx
WORKDIR /nginx-1.25.0
RUN ./configure \
    --with-http_ssl_module \
    --add-module=../redis2-nginx-module \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock && \
    make && \
    make install

# 第二阶段:运行阶段
FROM alpine:latest

# 更换软件源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories

# 安装运行时必要的依赖
RUN apk update && apk add --no-cache \
    pcre \
    zlib \
    openssl

# 创建新用户
RUN addgroup -S nginxgroup && \
    adduser -S -G nginxgroup nginxuser && \
    id nginxuser

# 复制编译好的Nginx文件
COPY --from=builder /etc/nginx /etc/nginx
COPY --from=builder /usr/sbin/nginx /usr/sbin/nginx

# 复制自定义的 Nginx 配置文件
COPY nginx.conf /etc/nginx/nginx.conf

# 复制 SSL 证书
COPY ssl/cert.pem /etc/nginx/ssl/cert.pem
COPY ssl/key.pem /etc/nginx/ssl/key.pem

# 创建必要的目录
RUN mkdir -p /var/log/nginx
RUN mkdir -p /var/run/nginx
RUN mkdir -p /var/cache/nginx

# 以 root 用户执行权限修复
USER root
RUN chown -R nginxuser:nginxgroup /etc/nginx /var/log/nginx /var/run/nginx /var/cache/nginx /etc/nginx/ssl

# 复制启动脚本
COPY start_nginx.sh /start_nginx.sh
# 以 root 用户修改启动脚本权限
RUN chmod +x /start_nginx.sh

# 暴露 80 和 443 端口
EXPOSE 80 443

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost/ || exit 1

# 以 root 用户启动脚本
CMD ["/start_nginx.sh"]

知识点讲解

  • 多阶段构建
    • 目的:将构建过程分为两个阶段,第一阶段(builder)用于构建 Nginx 并安装 Redis 模块,包含了许多构建工具和依赖,比较臃肿;第二阶段只复制第一阶段构建好的必要文件和运行时依赖,生成的最终镜像会非常精简,减少了镜像的体积,提高了安全性和部署效率。
    • 实现方式:通过 FROM alpine:latest AS builder 定义第一阶段,使用 COPY --from=builder 从第一阶段复制文件到第二阶段。
  • 基础镜像选择
    • 选择 alpine:latest 作为基础镜像,因为 Alpine Linux 非常轻量级,它的镜像体积很小,适合作为基础镜像来构建 Docker 镜像,能减少最终镜像的大小。
  • HEALTHCHECK 指令
    • 作用:用于定期检查容器的健康状态。
    • 配置:HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/ || exit 1,表示每隔 30 秒检查一次,如果 3 秒内 curl 请求本地地址失败,就认为容器不健康。
    • 应用场景:在容器编排系统(如 Docker Compose、Kubernetes)中自动重启不健康的容器。
2. nginx.conf
nginx 复制代码
user nginxuser nginxgroup;  # 指定用户和用户组
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

# 引入环境变量,放在 main 上下文
env BACKEND_SERVER;

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

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;

    server_tokens off;

    # 启用 Gzip 压缩
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 缓存配置
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=100m inactive=60m use_temp_path=off;

    # 定义 upstream 块
    upstream backend {
        server $BACKEND_SERVER;
    }

    # HTTP 服务器配置
    server {
        listen 80;
        server_name _;

        # 重定向 HTTP 请求到 HTTPS
        #return 301 https://$host$request_uri;
        proxy_redirect http:// https://;
    }

    # HTTPS 服务器配置
    server {
        listen 443 ssl;
        server_name _;

        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/key.pem;

        # 尝试代理请求到后端服务
        location / {
            proxy_pass http://backend;
            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;

            # 缓存配置
            proxy_cache my_cache;
            proxy_cache_valid 200 302 60m;
            proxy_cache_valid 404 1m;

            # 如果后端服务不可用,返回默认页面
            error_page 502 503 504 = @fallback;
        }

        # 错误页面配置
        error_page 500 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }

        # 备用页面配置
        location @fallback {
            root /usr/share/nginx/html;
            index index.html;
        }
    }
}

知识点讲解

  • 环境变量引入
    • 方式:在 nginx.conf 中使用 env BACKEND_SERVER; 引入环境变量,然后在 upstream 块中使用 $BACKEND_SERVER 作为后端服务器地址。
    • 作用:可以在运行容器时通过环境变量动态指定后端服务器地址,提高了配置的灵活性。
  • Gzip 压缩配置
    • 启用:gzip on; 开启 Gzip 压缩功能。
    • 参数配置:如 gzip_comp_level 6 表示压缩级别为 6,gzip_types 定义了需要压缩的文件类型。
    • 作用:减少数据传输量,提高网站的加载速度,尤其是对于文本类型的文件(如 HTML、CSS、JavaScript 等)效果明显。
  • 缓存配置
    • 缓存路径定义:proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=100m inactive=60m use_temp_path=off; 定义了缓存路径、缓存区大小等参数。
    • 缓存规则配置:在 location 块中使用 proxy_cache my_cache;proxy_cache_valid 200 302 60m; 配置缓存规则。
    • 作用:减少对后端服务器的请求次数,提高响应速度,尤其是对于一些静态资源或频繁访问的页面。
3. start_nginx.sh
bash 复制代码
#!/bin/sh

# 检查环境变量是否设置
if [ -z "$BACKEND_SERVER" ]; then
    echo "Warning: BACKEND_SERVER environment variable is not set. Using localhost (127.0.0.1) as the backend server."
    BACKEND_SERVER="127.0.0.1"
fi

# 替换 nginx.conf 中的占位符
sed -i "s|\$BACKEND_SERVER|$BACKEND_SERVER|g" /etc/nginx/nginx.conf

# 检查配置文件是否有效
nginx -t

# 以 root 用户启动 Nginx,Nginx 会根据 nginx.conf 中的 user 指令切换用户
exec nginx -g 'daemon off;'

知识点讲解

  • 环境变量检查与替换
    • 检查:使用 if [ -z "$BACKEND_SERVER" ]; then 检查 BACKEND_SERVER 环境变量是否设置。
    • 替换:如果未设置,则使用默认值 127.0.0.1,然后使用 sed 命令替换 nginx.conf 中的占位符。
    • 作用:确保在不同环境中 Nginx 都能正确连接到后端服务器。
  • 配置文件检查
    • 命令:nginx -t 用于检查配置文件是否有效。
    • 作用:避免因配置错误导致 Nginx 启动失败。

(三)生成自签名证书(测试环境)

bash 复制代码
mkdir ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout ssl/key.pem \
    -out ssl/cert.pem \
    -subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=Example Company/OU=IT Department/CN=example.com/[email protected]"

知识点讲解

  • OpenSSL 命令
    • 作用:使用 OpenSSL 生成自签名证书。
    • 参数解释:-x509 表示生成自签名证书,-nodes 表示不加密私钥,-days 365 表示证书有效期为 365 天,-newkey rsa:2048 表示生成 2048 位的 RSA 密钥,-subj 用于一次性设置证书的各种信息(如国家、省份、公司等)。
    • 应用场景:在测试环境中可以用来测试 HTTPS 连接,但在生产环境中建议使用正规的 CA 机构颁发的证书。

(四)构建镜像

bash 复制代码
docker build --cache-from nginx-1.25-redis-alpine -t nginx-1.25-redis-alpine . 

知识点讲解

  • docker build 命令
    • 参数解释:--cache-from 用于指定缓存镜像,-t 用于指定镜像的标签,最后的 . 表示使用当前目录作为构建上下文。
    • 作用:根据 Dockerfile 构建 Docker 镜像。

(五)运行容器

bash 复制代码
docker run -d -p 80:80 -p 443:443 nginx-1.25-redis-alpine

如果要指定后端服务器,可以继续使用 -e 参数:

bash 复制代码
docker run -d -p 80:80 -p 443:443 -e BACKEND_SERVER=backend_server_ip:backend_server_port nginx-1.25-redis-alpine

知识点讲解

  • 端口映射
    • 方式:使用 docker run -p 80:80 -p 443:443 将容器的 80 和 443 端口映射到主机的对应端口。
    • 作用:通过主机的 IP 地址访问容器内的 Nginx 服务。
  • 环境变量传递
    • 方式:使用 -e BACKEND_SERVER=backend_server_ip:backend_server_port 在运行容器时传递环境变量。
    • 作用:动态指定后端服务器地址。

访问测试curl localhost 看熟悉的Nginx欢迎页面来了。

bash 复制代码
curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

四、课程总结

通过本课程的学习,你应该对 nginx-redis-alpine 项目有了深入的理解,包括 Dockerfile 的多阶段构建、Nginx 的配置、启动脚本的编写、自签名证书的生成以及 Docker 镜像的构建和容器的运行等知识点。这些知识在实际的项目开发和运维中非常有用,希望你能熟练掌握并应用到实际工作中。

相关推荐
java知路19 分钟前
ubuntu修改时区
linux·运维·ubuntu
首席令狐冲2 小时前
docker 小记
运维·docker·容器
LCY1332 小时前
docker compose的使用
运维·docker·容器
ICT系统集成阿祥3 小时前
实验篇| CentOS 7 下 Keepalived + Nginx 实现双机高可用
linux·运维·服务器·nginx·centos
元气满满的热码式3 小时前
MySQL启动报错解决
运维·数据库·mysql
XMYX-04 小时前
解决 Redis 后台持久化失败的问题:内存不足导致 fork 失败
java·数据库·redis
椰椰椰耶4 小时前
【redis】set 类型:基本命令
数据库·redis·缓存
ikmb4 小时前
mac用docker跑sql server
macos·docker·容器
小二·4 小时前
Redis的缓存雪崩、缓存击穿、缓存穿透与缓存预热、缓存降级
redis·缓存·mybatis