Docker+alpine制作极简的HTTP服务

洪高刚
2023-12-01

一、Alpine Linux介绍

Alpine Linux是一个面向安全的轻型的Linux发行版。
Alpine Linux采用了 musl libc 和 busybox以减小系统的体积和运行时资源消耗。
在保持瘦身的同时,Alpine Linux还提供了自己的包管理工具apk。
关键的是,相比于其他Linux的Docker镜像,它的容量非常小,仅仅只有5MB。

Alpine Linux的官网:
http://www.alpinelinux.org/
https://pkgs.alpinelinux.org/packages

二、开始前准备

  1. 配置环境
# 拉取alpine镜像
root> docker pull alpine

# PS:  
#	1. 配置临时环境变量,不能关闭『终端』否则临时变量会失效。
#	2. windows无法使用环境变量,跳过这个步骤,后面手动填写环境变量的值。事实上也不建议使用Windows创建。
# 网站文件在宿主机中保存的位置,根据需要自行定义路径
root> export WWW_ROOT_PATH=/opt/wwwroot
# 镜像保存到本地的配置文件路径,根据需要自行定义路径
root> export DOCKER_DATA_PATH=/opt/docker-config

# 创建一个空白目录
root> mkdir /opt/docker-build

# 定位到刚创建的目录中
root> cd /opt/docker-build
  1. 创建临时镜像,获取基础配置目录
# 启用一个临时的容器
root> docker run -it \
           --name alpine-demo \
           --rm \
           alpine

# 安装容器工具
alpine-demo> sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
             && apk update \
             && apk add nginx \
             && apk add php8 php8-fpm

# 确认工具安装成功(安装成功,该两个文件夹必定存在)
alpine-demo> ls -l /etc/nginx
alpine-demo> ls -l /etc/php8

# --------------------  以下是上面组合命令的解释 -------------------------
# 设置容器管理工具镜像国内地址
alpine-demo> sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

# 更新包工具
alpine-demo> apk update

# 安装nginx
alpine-demo> apk add nginx

# 安装PHP
alpine-demo> apk add php8 \
        			 php8-fpm
  1. 不要关闭上面的『终端』,新建一个终端工具复制容器中的文件
# 定位到上面创建的目录中
root> cd /opt/docker-build

# 复制nginx配置到宿主机中,位置为上面创建的文件夹中。
root> docker cp alpine-demo:/etc/nginx ./

# 复制php配置到宿主机中,位置为上面创建的文件夹中。
root> docker cp alpine-demo:/etc/php8 ./

# 复制Linux时区到这个文件夹中(仅知道 macOS 和 Linux是有这个时区)
root> cp /usr/share/zoneinfo/Asia/Shanghai ./localtime
  1. 设置一下优化配置,给容器设置一些『环境』的概念。
# 添加php环境变量
# 以后希望能通过 docker run 传入环境变量
root> vi ./php8/php-fpm.d/www.conf

# 使用root启动PHP,否则无法读取环境变量
user = root
group = root
# 在431行添加环境变量,代码中用 getenv('PROJECT_ENV') 获取该环境值
env[PROJECT_ENV] = $PROJECT_ENV


# nginx的配置,
# ./nginx/nginx.conf
# 配置目录, 这里有个默认的配置文件,要修改一下,不然404. 使用时自定义配置,这里不多做介绍。
# ./nginx/http.d/*.conf
  1. 准备工作差不多了,现在可以关闭上面第一步创建的临时容器了。

三、使用 Dockerfile 定制镜像

  1. 找个空白的目录创建 Dockerfile 文件
# 创建 Dockerfile 文件
root> touch /opt/docker-build/Dockerfile

# 编辑 Dockerfile 文件 (事实上我是用vs Code编辑的)
root> vi /opt/docker-build/Dockerfile
  1. Dockerfile 文件内容
# http 服务部署
# VERSION 0.0.1
# Author: zzjun v@revery.top
FROM alpine

# 设置默认环境变量
ENV PROJECT_ENV=prod

# 复制本地时区到镜像
ADD ./localtime /etc/localtime
ADD ./nginx /etc/nginx
ADD ./php8 /etc/php8

# 指定暴露端口
EXPOSE 80 443

# 安装容器基础工具
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
    && apk update \
    && apk add --no-cache nginx \
    && apk add --no-cache php8 \
        php8-fpm \
        php8-opcache \
        php8-curl \
        php8-gd \
        php8-mbstring \
        php8-mysqli \
        php8-json \
        php8-redis \
        php8-zip \
        php8-ctype \
        php8-iconv \
        php8-openssl \
        php8-pcntl \
        php8-session \
        php8-posix \
        php8-pecl-event \
        php8-xmlwriter \
        php8-pdo \
        php8-pdo_mysql \
        php8-pdo_odbc \
     && apk add --no-cache tzdata \
     && echo "Asia/Shanghai" > /etc/timezone

# PS:
#   关于nginx启动方式的说明
#	1. 在常规的虚机上,nginx默认是以守护进程来运行的(daemon on),在后台默默提供服务,同时部署多个ngxin服务也不会相互干扰。
#	2. 在容器环境,one container == one process,容器要能持续运行,必须有且仅有一个前台进程,所以对nginx进程容器化,需要将nginx转为前后进程( daemon off)。
#   3. 参考文档:https://github.com/gliderlabs/docker-alpine/issues/185

# 设置容器启动后执行的命令行,这里启动PHP和nginx
ENTRYPOINT php-fpm8 -R \
           && nginx -g "daemon off;"
  1. 编译成新的镜像
# 编译一个镜像 (注意,后面有个『.』, 表示基于当前目录构建的)
root> docker build -t [新镜像名称]:[镜像版本号] .

# 例子
root> docker build -t docker-reverytop/http-service-template:v1.0.0 .

# 编译完成后,把当前目录的配置文件复制到环境变量中定义的目录中
root> cp -r ./nginx $DOCKER_DATA_PATH
root> cp -r ./php8 $DOCKER_DATA_PATH

四、容器运行

# 运行容器
root> docker run -itd \
        --name http-service \
        -v $WWW_ROOT_PATH:/var/lib/nginx/html \
        -v $DOCKER_DATA_PATH/nginx:/etc/nginx \
        -p 80:80 \
        -p 443:443 \
        -e PROJECT_ENV='dev' \
        docker-reverytop/http-service-template:v1.0.0

启动容器后,浏览器访问:http://127.0.0.1 看效果。

五、扩展

  1. 容器内部文件目录介绍
# nginx web 目录
/var/lib/nginx/html

# nginx 配置目录
/etc/nginx/

# php 配置目录
/etc/php8

# 日志目录
/var/log/php8/error.log
/var/log/nginx/error.log
/var/log/nginx/access.log
  1. php 组件,
# PHP参考组件
php8-fpm 
php8-mcrypt 
php8-soap 
php8-openssl 
php8-gmp 
php8-pdo_odbc 
php8-json 
php8-dom 
php8-pdo 
php8-zip 
php8-mysqli 
php8-bcmath 
php8-gd 
php8-odbc 
php8-pdo_mysql 
php8-gettext 
php8-xmlreader 
php8-xmlrpc 
php8-bz2 
php8-iconv 
php8-curl 
php8-ctype 
php8-redis

完!

 类似资料: