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