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/emailAddress=admin@example.com"

知识点讲解

  • 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 镜像的构建和容器的运行等知识点。这些知识在实际的项目开发和运维中非常有用,希望你能熟练掌握并应用到实际工作中。

相关推荐
XIAOHEZIcode1 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220702 天前
如何搭建本地yum源(上)
运维
武子康2 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
ping某3 天前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
用户3169353811833 天前
Java连接Redis
redis
大树885 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠5 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质5 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小小工匠5 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
Inhand陈工5 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信