编写Dockerfile
最近在部署项目事,想做一个基于ubuntu20.04,搭建nginx + php8.*的镜像。但是在制作的过程中遇到了很多坑,记录下来供后续参考学习。
修改镜像过程大概分为了6个模块:
- 模块一:对ubuntu 20.04官方镜像重新构造。
- 模块二:在基础镜像添加php8.*的源
- 模块三:安装nginx、php以及相关依赖。
- 模块四:设置nginx、php配置文件
- 模块五:编写nginx、php-fpm8.*启动脚本文件
- 模块六:镜像打包与验证。
1、创建Dockerfile文件,基于ubuntu20.04官方镜像编写。
创建项目目录、创建Dockerfile文件。
#创建项目目录
mkdir laravel-crm
#切换至项目目录
cd laravel-crm
#创建Dockerfile文件
touch Dockerfile
touch nginx.conf
touch php.ini
touch phpinfo.php
对ubuntu 20.04官方镜像重新构造,使用LABEL 参数设置了运营人员信息。使用apt-get安装软件时,ubuntu20.04 系统自带的源太慢,将apt-get源修改为国内任意可用源地址,这里以清华大学源为例。
使用sed -i 替换/etc/apt/sources.list 镜像,替换之后使用apt-get clean,apt-get update更新ubuntu20.40最新源地址,如以下代码所示。
# 基础镜像是 Ubuntu 20.04(可使用本地已存在的镜像作为基础)
FROM ubuntu:20.04
#镜像维护人员
LABEL maintainer="yangfan<834551859@qq.com>"
#ubuntu apt-get原镜像太慢了,替换国内的镜像,这里是以清华大学镜像为例。
RUN sed -i s:/archive.ubuntu.com:/mirrors.tuna.tsinghua.edu.cn/ubuntu:g /etc/apt/sources.list
RUN cat /etc/apt/sources.list
RUN apt-get clean
RUN apt-get -y update
#设置服务器时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
2.在基础镜像添加php8.*的源
ubuntu 20.04本身的php版本最高时php7.4.,而要求是要安装php8.,查阅相关安装资料,安装命令如下:
#命令一
apt-get install ca-certificates apt-transport-https software-properties-common
#命令二
add-apt-repository ppa:ondrej/php
3.安装nginx、php以及相关依赖
#安装nginx
RUN apt-get update \
&& apt-get install -y nginx \
php8.2 php8.2-fpm php8.2-dev \
php8.2-gd php8.2-curl php8.2-bz2 php8.2-bcmath \
php8.2-imap php8.2-mysql php8.2-mbstring \
php8.2-xml php8.2-zip php8.2-soap \
php8.2-msgpack php8.2-igbinary php8.2-ldap \
php8.2-redis php8.2-intl \
&& php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# nginx默认启动用户是www-data用户 www-data组,当php-fpm8.* 运行时生成php8.*-fpm.sock有权限
RUN mkdir -p /run/php && chown www-data:www-data /run/php
nginx默认启动用户是www-data用户 www-data组,因此需要给 /run/php文件夹授权,在php-fpm8. 运行时可以生成php8.-fpm.sock文件。
4.设置nginx、php配置文件
#将指定文件夹内容copy到容器里面
COPY nginx.conf /etc/nginx/nginx.conf
COPY php.ini /etc/php/8.2/fpm/php.ini
#创建工作目录文件夹
RUN mkdir -p /var/www/html
ADD start.sh /var/www/html
ADD . /var/www/html
5.编写nginx、php-fpm8.*启动脚本文件
Dockerfile文件中使用CMD就可以运行程序或者脚本文件,但是当一个Dockerfile出现多个CMD的时候,自上而下执行最后一个。我们期望在docker容器启动时,分别启动nginx、php-fpm8.*,则需要放在脚本文件里面进行启动。
#工作目录
WORKDIR /var/www/html
#对外暴露端口
EXPOSE 80
EXPOSE 443
EXPOSE 9000
#CMD 指令指定在容器启动时执行的命令
#CMD ["sh","-c","php-fpm7.4"]
#CMD ["nginx","-g","daemon off;"]
CMD ["./start.sh"]
根据上面5个模块,最终Dockerfile脚本文件如下。
# 基础镜像是 Ubuntu 20.04(可使用本地已存在的镜像作为基础)
FROM ubuntu:20.04
#镜像维护人员
LABEL maintainer="yangfan<834551859@qq.com>"
#ubuntu apt-get原镜像太慢了,替换国内的镜像,这里是以清华大学镜像为例。
RUN sed -i s:/archive.ubuntu.com:/mirrors.tuna.tsinghua.edu.cn/ubuntu:g /etc/apt/sources.list
RUN cat /etc/apt/sources.list
RUN apt-get clean
RUN apt-get -y update
#设置服务器时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 扩展依赖
RUN apt-get install -y \
apt-utils \
curl \
git \
apt-transport-https \
software-properties-common \
g++ \
build-essential
#ubuntu 20.04 apt 安装 PHP8.0
RUN add-apt-repository -y ppa:ondrej/php
RUN apt-get update \
&& apt-get install -y dialog \
whiptail
#安装nginx
RUN apt-get update \
&& apt-get install -y nginx \
php8.2 php8.2-fpm php8.2-dev \
php8.2-gd php8.2-curl php8.2-bz2 php8.2-bcmath \
php8.2-imap php8.2-mysql php8.2-mbstring \
php8.2-xml php8.2-zip php8.2-soap \
php8.2-msgpack php8.2-igbinary php8.2-ldap \
php8.2-redis php8.2-intl \
&& php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer \
&& apt-get -y autoremove \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# nginx默认启动用户是www-data用户 www-data组,当php-fpm8.* 运行时生成php8.*-fpm.sock有权限
RUN mkdir -p /run/php && chown www-data:www-data /run/php
#将指定文件夹内容copy到容器里面
COPY nginx.conf /etc/nginx/nginx.conf
COPY php.ini /etc/php/8.2/fpm/php.ini
#创建工作目录文件夹
RUN mkdir -p /var/www/html
ADD start.sh /var/www/html
ADD . /var/www/html
RUN chmod +x /var/www/html/start.sh
#工作目录
WORKDIR /var/www/html
#对外暴露端口
EXPOSE 80
EXPOSE 443
EXPOSE 9000
#CMD 指令指定在容器启动时执行的命令
#CMD ["sh","-c","php-fpm7.4"]
#CMD ["nginx","-g","daemon off;"]
CMD ["./start.sh"]
nginx.conf配置文件如下:
# 全局配置
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
events {
worker_connections 1024;
}
# http 配置
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 访问日志配置
access_log /var/log/nginx/access.log;
# 服务器块
server {
listen 80;
server_name localhost;
#laravel配置目录,根据自己项目需要,重新设置文件目录;
root /var/www/html/public;
location / {
index index.php index.html;
try_files $uri $uri/ /index.php?$query_string;
if (!-e $request_filename){
rewrite ^/(.*) /index.php last;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html/public;
}
location ~ \.php(.*)$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi_params;
include fastcgi.conf;
}
}
}
php.ini配置文件,如下:
; Execution, size, upload
max_input_time = 60
max_execution_time = 60
memory_limit = 256M
post_max_size = 56M
upload_max_filesize = 56M
output_buffering = 4096
realpath_cache_size = 4096k
realpath_cache_ttl = 600
;
; ; Error
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
;
; ; Security
allow_url_fopen = Off
allow_url_include = Off
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
;
; ; Misc
request_order = "GP"
variables_order = "GPCS"
register_argc_argv = Off
short_open_tag = Off
zend.assertions = -1
; [CLI Server]
cli_server.color = On
; [Session]
session.sid_bits_per_character = 5
session.gc_divisor = 1000
session.sid_length = 26
; [mysqlnd]
mysqlnd.collect_statistics = Off
mysqlnd.collect_memory_statistics = Off
; [opcache]
opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=32531
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1
start.sh脚本如下:
#!/bin/bash
echo "------------nginx start-----"
cd /usr/sbin
pwd
policy-rc.d
php-fpm8.2 -D
nginx -g "daemon off;"
ps aux | grep nginx
ps aux | grep php-fpm
echo "------------nginx end -----"
phpinfo.php文件内容如下:
<?php
phpinfo();
?>
6.镜像打包与验证。
在laravel-crm文件夹执行镜像打包命令,并验证镜像文件是否已生成。
docker build -t "yangfanubuntu:v1.4" .
使用 docker images 查看本机所有镜像,确实有一个名字叫yangfanubuntu:v1.4的镜像,说明自定义镜像文件已经生成。
使用yangfanubuntu:v1.4镜像创建容器
-p 指定端口号
-d 允许容器后台运行
--name 设置镜像名字
docker run -it -d -p 8088:80 --name=laravel-crm yangfanubuntu:v1.4
使用docker ps -a 查看是否生成laravel-crm容器
验证nginx + php8.*是否成功。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。