Docker

Docker安装

Docker安装

官网手册地址:点击此处

可以直接安装 yum -y install docker-ce 如果安装版本较低,就先卸载然后按照如下步骤安装

卸载旧版本的docker

yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

也可以 rpm -qa | grep docker 找出安装包后卸载

安装需依赖

yum install -y yum-utils device-mapper-persistent-data lvm2

设置Docker yum源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

查看所有仓库中所有docker版本

yum list docker-ce --showduplicates | sort -r

安装docker

yum install -y docker-ce

安装特定版本

yum install docker-ce-18.06.1.ce

设置开机启动

systemctl enable docker

启动

systemctl start docker

查看状态

systemctl status docker

解决 docker pull 速度慢问题

# 打开或创建该文件
vim /etc/docker/daemon.json

# 输入或修改内容,找个快的镜像源
{
  "registry-mirrors":["https://vlk771j5.mirror.aliyuncs.com"]
}

Windows安装

Windows安装时,如果出现报错如下:

Docker Desktop requires Windows 10 Pro/Enterprise/Home version 19044 or above.

解决方法一:升级系统版本到指定要求

解决办法二:修改系统版本信息

输入cmd命令,运行regedit,回车,出现注册表编辑器,找到:计算机\HKEY LOCAL MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion。确认EditionId是否为Professional,如果不是对其进行修改。

参考:https://blog.csdn.net/qq_30776829/article/details/143705124

镜像

镜像的使用

列出本机容器

docker imagesdocker image lsdocker images -a

参数 说明
REPOSITORY 表示镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像ID
CREATED 镜像创建时间
SIZE 镜像大小

同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本。

我们使用 REPOSITORY:TAG 来定义不同的镜像。

如果运行时没有指定版本,则会默认运行最新的。

仓库名和标签都显示为 <none> 的镜像为悬挂镜像,是由于官方维护了新镜像,取消旧镜像导致的,一般来说,可以随意删除

  • 显示悬挂镜像 docker images -f dangling=true

  • 删除悬挂镜像 docker image prune

列出部分镜像

docker images ubuntu

docker images ubuntu:18.04

列出 mongo:3.2 之后建立的镜像 docker image ls -f since=mongo:3.2

列出 mongo:3.2 之前建立的镜像 docker image ls -f before=mongo:3.2

通过 LABEL 过滤 docker image ls -f label=com.example.version=0.1

查找镜像

一、去 DockerHub 网站搜索镜像 https://hub.docker.com/

二、命令行查找镜像 docker search nginx

参数 说明
NAME 镜像仓库源的名称
DESCRIPTION 镜像的描述
STARS 类似 Github 里面的 star,表示点赞、喜欢的意思
OFFICIAL 是否为官方发布
AUTOMATED 自动构建

下载镜像

格式: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

  • 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 DockerHub
  • 仓库名:这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 DockerHub 如果不给出用户名,则默认为 library 也就是官方镜像。
  • 标签:可以理解为版本号

例如:拉取官方 php:7.4-fpm 镜像 docker pull php:7.4-fpm

当我们从docker镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

一、从已经创建的容器中更新镜像,并且提交这个镜像

二、使用 Dockerfile 指令来创建一个新的镜像

更新镜像

暂无

构建镜像

基于当前某个容器打包镜像

docker commit 5baaffcc5678 sxy/test:v4

设置镜像标签

暂无

删除本地镜像

格式: docker image rm [选项] <镜像1> [<镜像2> ...]

例如: docker rmi php:7.4-fpm

使用 Dockerfile 定制镜像

下载一个nginx镜像

docker pull nginx

运行以下

docker run --name my_nginx -d -p 8080:80 nginx

本机访问

127.0.0.1:8080

编写 dockerfile 文件

在本机创建一个空白目录,用来存放 DockerFile 文件,或者你随意找个地方放

一个简单的 dockerfile 文件填写样式

文件名 /root/dockerfile/nginx_v3
## 拉取Nginx镜像
FROM nginx

## 将 echo 后的内容写入到容器内的相应目录下的相应文件中
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

构建镜像

docker build -t nginx:v3 .

-f 指定文件
docker build -f /root/dockerfile/nginx_v3 -t nginx:v4 .

查看本地镜像

查看本地镜像,发现多了一个 nginx:v3 的

运行这个 nginx:v3 docker run --name nginx_v3 -d -p 8080:80 nginx:v3

详解

FROM 指定基础镜像

找到一个优秀的基础镜像,在这个镜像上面来做一些修改

有一个特殊镜像 scratch 这是一个虚拟镜像,并不实际存在,如果指定这个,就表示不以任何镜像为基础,自己写镜像的第一层

RUN 执行命令

RUN 指令是用来执行命令行命令的

  • shell 格式:RUN <命令>, 比如 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html 就是这种格式

  • exec 格式:RUN ["可执行文件", "参数1", "参数2"]

比如:

FROM debian:stretch

RUN apt-get update
RUN apt-get install -y gcc libc6-dev make wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install

构建镜像

docker build [选项] <上下文路径/URL/->

示例:docker build -t nginx:v3

镜像构建上下文(Context)

Dockerfile 指令详解

Dockerfile 指令详解

参考文档吧:点击此处

COPY 复制文件

格式:

  • COPY [--chown=<user>:<group>] <源路径>... <目标路径>

  • COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

将从构建上下文目录中 <源路径> 的文件或目录复制到新的一层的镜像内的 <目标路径> 位置

可以是多个文件,可以设置通配符,目标路径可以是相对路径,也可以是绝对路径,容器内会自动创建目录

# 普通复制
COPY package.json /usr/src/app/

# 通配符
COPY hom* /mydir/
COPY hom?.txt /mydir/

ADD 更高级的复制文件

不建议使用,官方说最好用 COPY

CMD 容器启动命令

上传镜像

上传镜像

注意事项:

  1. 先去创建一个 docker 账号
  2. 创建仓库,注意仓库名称,到时候创建的镜像要和这个名称一模一样才行
docker login -u shuxiaoyuan
docker push shuxiaoyuan/php74:v1.3

基于当前某个容器打包镜像

docker commit 5baaffcc5678 sxy/test:v4

上传

docker push sxy/test:v4

上传阿里云

进入 阿里云容器镜像服务

设置好用户名密码,镜像名称,命名空间等等

登录: docker login --username=shu.xiaoyuan@163.com registry.cn-shanghai.aliyuncs.com

上传镜像:

docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/shuxiaoyuan/php74:[镜像版本号]
docker push registry.cn-shanghai.aliyuncs.com/shuxiaoyuan/php74:[镜像版本号]

容器

启动容器

docker run --name my_nginx -d -p 8080:80 nginx:v3

常用参数 说明
- - name 容器名,不能重复(包括已停止的启动等)
-d 后台运行
-P 容器内部端口随机映射到主机的高端口
-p 指定端口映射,本机端口:容器内端口
-t 在新容器内指定一个伪终端或终端
-i 允许你对容器内的标准输入 (STDIN) 进行交互
- - rm 容器退出后随之将其删除

后台运行

容器启动时加上 -d 参数

终止容器

docker stop 容器ID | 容器名

进入容器

docker exec -it nginx /bin/bash 如果报错找不到 /bin/bash 可以替换为 /bin/sh

导入/导出容器

docker export 容器ID > xxx.tar

cat ubuntu.tar | docker import - test/ubuntu:v1.0

docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器

docker rm 容器名 | 容器ID

删除运行中的容器 docker rm -f 容器ID | 容器名

删除所有处于终止状态的容器 docker container prune

查看容器报错日志

#查看末尾3000行
docker logs --tail 3000  e0864b9d33ef

#滚动最后100行
docker logs -f --tail 100  e0864b9d33ef

#最后3000带查询
docker logs --tail 3000  e0864b9d33ef  | grep 'sql='
docker logs --tail 10000  e0864b9d33ef  | grep '节点名称=输出'
docker logs --tail 10000  e0864b9d33ef  | grep 'Exception'

#输出到文件
docker logs --tail 1000  e0864b9d33ef   >> logs_error.txt

docker compose(建议)

容器互联

容器互联

官方强烈建议,放弃古老的 --link 方式,故下文不介绍该方式

虚拟 IP 方式(不建议)

bridge 网络方式(建议)

创建一个网络 docker network create -d bridge lnmpr-net

移除一个网络 docker network rm lnmpr-net

查看所有网络 docker network ls

容器离开自定义网络 docker network disconnect lnmpr-net nginx

查看指定网络 docker network inspect lnmpr-net,内容如下

[
  {
    "Name": "lnmpr-net",
    "Id": "625377cf57851373e929f572dd8901727d842240f0b4c61b284b9bba6893dd30",
    "Created": "2021-08-23T06:23:30.844869Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
        {
          "Subnet": "172.19.0.0/16",
          "Gateway": "172.19.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {},
    "Options": {},
    "Labels": {}
  }
]

运行相应容器,并加入 lnmpr-net 网络

# 运行 MySQL 并加入网络
docker run --name mysql_3 -itdp 10003:3306 -e MYSQL_ROOT_PASSWORD=123456 --mount type=bind,source=D:/Docker/MySQL,target=/var/lib/mysql --network lnmpr-net mysql:8.0.26

# 运行 Redis 并加入网络
docker run --name redis -dp 20000:6379 --mount type=bind,source=D:/Docker/Redis,target=/data --network lnmpr-net redis:6 redis-server /data/docker_redis.conf --appendonly yes

查看 lnmpr-net 网络,docker network inspect lnmpr-net,内容如下

[
  {
    "Name": "lnmpr-net",
    "Id": "625377cf57851373e929f572dd8901727d842240f0b4c61b284b9bba6893dd30",
    "Created": "2021-08-23T06:23:30.844869Z",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv6": false,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
        {
          "Subnet": "172.19.0.0/16",
          "Gateway": "172.19.0.1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
      "05c5e4f414e1a64e4ff11c484d7d218450a3acef444c42e84bf88046753ee77a": {
        "Name": "redis",
        "EndpointID": "419c3c7dd626e0bce41d5ac735514138530f64f4d58eeb86830ab4deb47a5b44",
        "MacAddress": "02:42:ac:13:00:03",
        "IPv4Address": "172.19.0.3/16",
        "IPv6Address": ""
      },
      "ba89624fcb22a0300686cf3f229aa38be367b599a2c05b4096fa5f608e51700e": {
        "Name": "mysql_3",
        "EndpointID": "0488c679bf7b5534a478db716c53475f3b72d35add58c404b708d42fa35bd2e3",
        "MacAddress": "02:42:ac:13:00:02",
        "IPv4Address": "172.19.0.2/16",
        "IPv6Address": ""
      }
    },
    "Options": {},
    "Labels": {}
  }
]

测试是否能互通,进入相应的容器,使用 ping 命令即可,若提示命令没找到,执行安装语句 apt-get update && apt install iputils-ping

将运行中的容器连接到已经存在的用户自定义网桥

docker network connect my-net my-nginx

断开容器到用户自定义网络的连接

docker network disconnect my-net my-nginx

给运行的容器添加端口映射

查找容器ID

docker ps -a | grep nginx

根据短ID查找容器全名ID

docker inspect 66b3f8fc31e7 | grep Id

进去相应目录

cd /var/lib/docker/containers

# 在该目录下,进去打全容器ID的目录
cd 66b3f8fc31e78bf6464e542830957dbe15a410235c73ec4bbd3d9445b404d359

停止容器

systemctl stop docker

# 如果有警告提示如下:
Warning: Stopping docker.service, but it can still be activated by:
  docker.socket

# 再执行如下命令
systemctl stop docker.socket

修改两个JSON文件

hostconfig.json 和 config.v2.json 文件

vim hostconfig.json
#格式如:"{容器内部端口}/tcp":[{"HostIp":"","HostPort":"映射的宿主机端口"}]
 "PortBindings":{
        "80/tcp":[
            {
                "HostIp":"",
                "HostPort":"80"
            }
        ],
        "443/tcp":[
            {
                "HostIp":"",
                "HostPort":"443"
            }
        ]
    },

vim config.v2.json
# 修改 ExposedPorts 和 Ports 键值

"ExposedPorts":{
    "80/tcp":{

    },
    "443/tcp":{

    }
},

"Ports":{
    "443/tcp":[
        {
            "HostIp":"0.0.0.0",
            "HostPort":"443"
        },
        {
            "HostIp":"::",
            "HostPort":"443"
        }
    ],
    "80/tcp":[
        {
            "HostIp":"0.0.0.0",
            "HostPort":"80"
        },
        {
            "HostIp":"::",
            "HostPort":"80"
        }
    ]
},

启动 docker

systemctl start docker

查看是否添加了 443 端口

CONTAINER ID   IMAGE                       COMMAND                  CREATED      STATUS         PORTS                                                  NAMES
51d9ce87fd4b   shuxiaoyuan/php:8.0.28.v1   "docker-php-entrypoi…"   8 days ago   Up 4 seconds   9000/tcp                                               php80
c6ab470f7a66   shuxiaoyuan/php74:v1.3      "docker-php-entrypoi…"   8 days ago   Up 3 seconds   9000/tcp                                               php74
dd52673f2c71   mysql:8.0.33                "docker-entrypoint.s…"   8 days ago   Up 3 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql
9486d10f6aed   redis:7                     "docker-entrypoint.s…"   8 days ago   Up 2 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis7
66b3f8fc31e7   nginx:1.25.0                "/docker-entrypoint.…"   8 days ago   Up 2 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp             nginx

数据管理

数据卷

  • 可在容器之间共享和使用

  • 数据卷 的修改会立马生效

  • 数据卷 的更新,不会影响镜像

  • 默认会一直存在,即使容器被删除

创建一个数据卷

docker volume create my-vlo

查看所有数据卷 docker volume ls

查看指定数据卷的信息 docker volume inspect my-vlo

启动一个挂载数据卷的容器

在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷

docker run -d -P \
    --name web \
    # -v my-vol:/usr/share/nginx/html \
    --mount source=my-vol,target=/usr/share/nginx/html \
    nginx:alpine

上述创建了一个名为 web 的容器,并加载了一个 数据卷 到容器的 /usr/share/nginx/html 目录

查看数据卷的具体信息

docker inspect web

删除数据卷

docker volume rm my-vol

挂载主机目录

挂载一个主机目录作为数据卷

使用 --mount 标记可以指定挂载一个本地主机的目录到容器中去。

 docker run -d -P \
    --name web \
    --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html \
    nginx:alpine

加载主机的 /src/webapp 目录到容器的 /usr/share/nginx/html 目录

本地目录的路径必须是绝对路径

搭载的主机目录默认是 读写 权限,可以改为只读模式,如果改为只读模式了,那么在容器内这个目录下新建文件会报错的哦

docker run -d -P \
    --name web \
    --mount type=bind,source=/src/webapp,target=/usr/share/nginx/html,readonly \
    nginx:alpine

查看数据卷的具体信息

docker inspect web

挂载的主机目录在 Mounts 键下面

搭载一个本地主机文件作为数据卷

--mount 标记也可以从主机挂载单个文件到容器中

这样可以记录在容器内输入过的命令

docker run --rm -it \
   --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
   ubuntu:18.04 \
   bash

PHP开发环境

创建一个网络 docker network create -d bridge lnmpr-net

# 运行 MySQL 并加入网络
docker run --name mysql_3 -itdp 10003:3306 -e MYSQL_ROOT_PASSWORD=123456 --mount type=bind,source=D:/Docker/MySQL,target=/var/lib/mysql --network lnmpr-net mysql:8.0.26

# 运行 Redis 并加入网络
docker run --name redis -dp 20000:6379 --mount type=bind,source=D:/Docker/Redis,target=/data --network lnmpr-net redis:6 redis-server /data/docker_redis.conf --appendonly yes

# 运行 Nginx 容器并加入网络
docker run -d -p 30000:80 --name nginx_1 --mount type=bind,source=D:/Docker/Nginx/www,target=/usr/share/nginx/html --mount type=bind,source=D:/Docker/Nginx/logs,target=/var/log/nginx --mount type=bind,source=D:/Docker/Nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf --mount type=bind,source=D:/Docker/Nginx/conf/conf.d,target=/etc/nginx/conf.d --network lnmpr-net nginx:1.21

# 运行 php-fpm 容器并加入网络
docker run --name fpm_8 -d --mount type=bind,source=D:/Docker/Nginx/www,target=/var/www/html --network lnmpr-net php:8.0.9-fpm

如果是宿主机安装 nginx

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b63ff19872f3 localhost/uploadcenter/php80:v1.0 php-fpm 8 weeks ago Up 8 weeks ago 0.0.0.0:9100->9000/tcp php80

如果是宿主机安装 nginx 的话,那么 PHP 容器就需要将端口映射出来了,具体的 nginx 配置文件如下:

server {
    if ($host = demo.shuxiaoyuan.com) {
        return 301 https://$host$request_uri;
    }

    listen      80;
    server_name  demo.shuxiaoyuan.com;
    rewrite ^ https://demo.shuxiaoyuan.com/$request_uri? permanent;
}

server {
    listen       443;
    server_name  demo.shuxiaoyuan.com;

    ssl_certificate /usr/local/nginx/conf/ssl/demo.shuxiaoyuan.com.pem;
    ssl_certificate_key /usr/local/nginx/conf/ssl/demo.shuxiaoyuan.com.key;

    root   /www/upload-center/public;

    add_header 'Access-Control-Allow-Origin' *;
    add_header 'Access-Control-Allow-Headers' *;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' *;

    location / {
        index index.php index.htm index.html;

        try_files $uri $uri/ /index.php?$query_string;
    }

    # 注意此处的配置,php-fpm 将 9100 端口映射出来了
    location ~ \.php$ {
        root /www/upload-center;
        fastcgi_pass   127.0.0.1:9100;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/upload-center/public/$fastcgi_script_name;
        include        fastcgi_params;
    }
}

注意,注意

将 PHP 并入到网络中后,如果需要运行 PHP 代码,需要配置 nginx,上面的例子中,将 nginx 的配置文件 使用数据卷映射到本地了,所以我们只需要修改相应的 nginx 配置,部分配置如下

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm index.php;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        root           /var/www/html;
        fastcgi_pass   fpm_7.4:9000;
        fastcgi_index  index.php;

        # 特别需要注意这条语句,将 /var/www/html 替换为你真实的目录
        fastcgi_param  SCRIPT_FILENAME /var/www/html$fastcgi_script_name;

        include        fastcgi_params;
    }
}
Docker - Nginx

docker安装Nginx

查找、安装镜像

查找镜像 docker search nginx

安装镜像 docker pull nginx

指定版本安装 docker pull nginx:1.17

安装nginx镜像

简单的启动Nginx容器

docker run --name nginx1 -p 10000:80 -d nginx

docker run --name nginx2 -p 10001:80 -d nginx

参数 说明
- -name 设置容器名,要唯一
-d 让容器后台运行
-p 端口映射 本地端口:容器端口

会生成一长串的字符串,这个是容器的长 ID,一般可作为日志的文件名。

因为容器的特性,所以你可以启动多个nginx,启动多个确保 --name 的名字不一样,可以通过 docker ps -a 来查看所有容器,运行中的和未运行的,如果需要删除相应的容器,需要先将容器停止 docker stop nginx 然后删除 docker rm nginx

进入nginx容器

docker exec -it 容器ID名 或 容器名 /bin/bash 然后就跟操作 Linux 基本一样的了。

挂载数据卷

创建数据卷 | 挂载目录主机

# 创建三个数据卷
docker volume create www
docker volume create logs
docker volume create conf

# 创建三个本地目录
mkdir -p  nginx1/www nginx1/logs nginx1/conf nginx1/conf/conf.d
  • www nginx 容器配置的虚拟目录
  • logs nginx 容器的日志目录
  • conf nginx 容器的配置文件目录

部署配置文件

  1. 从容器中复制配置文件,容器要先运行起来才行啊 docker cp nginx:/etc/nginx/nginx.conf ~/nginx/conf

  2. 从其他地方复制过来配置文件,略

部署

使用数据卷

# 启动容器
docker run -d -p 10000:80 --name nginx1 --mount source=www,target=/usr/share/nginx/html --mount source=logs,target=/var/log/nginx --mount source=conf,target=/etc/nginx/conf.d --mount type=bind,source=/root/nginx1/conf/nginx.conf,target=/etc/nginx/nginx.conf nginx

# 访问
http://192.168.174.130:10000/

查看数据卷信息 docker volume inspect www 可以找到数据卷的位置信息 /var/lib/docker/volumes/www/_data

  • 修改首页文件 进入该文件中,修改 index.html 文件内容后,再次访问,查看页面内容是否改变

使用挂载主机目录

和使用数据类似

docker run -d -p 10000:80 --name nginx1 --mount type=bind,source=/root/nginx1/www,target=/usr/share/nginx/html --mount type=bind,source=/root/nginx1/logs,target=/var/log/nginx --mount type=bind,source=/root/nginx1/conf/nginx.conf,target=/etc/nginx/nginx.conf nginx

其他

如果要重新载入 NGINX 可以使用以下命令发送 HUP 信号到容器: docker kill -s HUP nginx

重启 NGINX 容器命令: docker restart nginx

Docker - Redis

Redis 容器

简单启动

默认是没有配置文件的

# 启动 Redis 容器
docker run --name redis -d -p 20000:6379 redis:6

# 进入容器
docker exec -it redis bash

以配置文件启动

准备一份配置文件,去网上找份全的,或者就用我的,只要写几个就行

# Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
daemonize yes

# 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid

# 指定Redis监听端口,默认端口为6379
# 如果指定0端口,表示Redis不监听TCP连接
port 6379

# 绑定的主机地址
# 你可以绑定单一接口,如果没有绑定,所有接口都会监听到来的连接
# bind 127.0.0.1

requirepass 123456

使用配置文件运行 Redis

docker run --name redis -dp 20000:6379 --mount type=bind,source=D:/Docker/Redis,target=/data redis:6 redis-server /data/docker_redis.conf --appendonly yes
Docker - MySQL

docker安装MySQL

查找安装MySQL

如果不指定版本号,默认就是拉取最新的

docker search mysql

docker pull mysql

运行容器

docker run --name mysql -it -d -p 10001:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /root/mysql:/var/lib/mysql mysql
  • -e MYSQL_ROOT_PASSWORD=123456 初始化 root 用户的密码。

利用客户端工具来连接MySQL,可以连接上,OK

最好是采用数据卷来存放 MySQL 的数据,避免容器销毁了数据也没了

进入容器进行MySQL操作

进入容器 docker exec -it mysql /bin/bash 登录MySQL服务器 mysql -uroot -p

接下来就是分配帐号,权限等等了

Docker - PHP

docker安装PHP

查找下载PHP镜像

docker search php

docker pull php:7.4-fpm

启动PHP容器

docker run --name php-fpm7.4 -v /root/nginx/www/:/www -d php:7.4-fpm

安装扩展

进入 php-fpm 容器 docker exec -it php-fpm7.4 bash

查看安装的扩展 php -m

安装 pdo_mysql 扩展 docker-php-ext-install pdo_mysql

常用命令:

  • docker-php-source 在容器中创建 /usr/src/php 文件夹

  • docker-php-ext-install 扩展名 安装并启动扩展(常用)

  • docker-php-ext-enable 扩展名 启动PHP扩展

  • docker-php-ext-configure 添加扩展自定义配置,和 enable 搭配使用

如果需要安装 zip 扩展:

安装相应依赖:apt-get update && apt-get install -y zlib1g-dev && apt-get install -y libzip-dev

安装并启动 zip 扩展 docker-php-ext-install zip

可用扩展,有些扩展可以直接安装,有些可能需要依赖包:

bcmath、bz2、calendar、ctype、curl、dba、dom、enchant、exif、ffi、fileinfo、filter、ftp、gd、gettext、gmp、hash、iconv、imap、intl、json、ldap、mbstring、mysqli、oci8、odbc、opcache、pcntl、pdo、pdo_dblib、pdo_firebird、pdo_mysql、pdo_oci、pdo_odbc、pdo_pgsql、pdo_sqlite、pgsql、phar、posix、pspell、readline、reflection、session、shmop、simplexml、snmp、soap、sockets、sodium、spl、standard、sysvmsg、sysvsem、sysvshm、tidy、tokenizer、xml、xmlreader、xmlrpc、xmlwriter、xsl、zend_test、zip

重启php容器 docker restart php-fpm7.4

安装 Redis 扩展

docker exec -it php bash

pecl install -o -f redis

# 在 php.ini 中添加 extension=redis.so
cd /usr/local/etc/php
cp php.ini-production php.ini

# 容器内一般是没装 vim 或者 vi 的,所有用下面方式写入内容到文件
echo "extension=redis.so" >> /usr/local/etc/php/php.ini

# 查看是否启用了扩展
php -m | grep redis

安装 swoole

## 方式一:
docker exec -it php bash

pecl install swoole

echo "extension=swoole.so" >> /usr/local/etc/php/php.ini

## 方式二:
docker-php-ext-install swoole
// 上面命令如果安装失败,会告诉你error: /usr/src/php/ext/swoole does not exist
// 然后下载 swoole 源码包,解压后放入到 /usr/src/php/ext/swoole 中
// 然后再次执行 docker-php-ext-install swoole

默认安装扩展

Core
ctype
curl
date
dom
fileinfo
filter
ftp
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib

安装完成后的扩展

bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zip
zlib

将nginx和PHP容器链接起来

创建目录:mkdir -p ~/nginx/conf/conf.d

在该目录下添加 test.com.conf 文件,内容如下:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm index.php;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/$fastcgi_script_name;
        include        fastcgi_params;
    }
}
参数 说明
root 该目录映射到 /root/nginx/www
fastcgi_param /www 为启动PHP容器的目录,映射到本地

启动nginx

docker run --name php-nginx -p 10000:80 -d \
    -v ~/nginx/www:/usr/share/nginx/html:ro \
    -v ~/nginx/conf/conf.d:/etc/nginx/conf.d:ro \
    --link php-fpm71:php \
    nginx
  • ro 只读

  • --link php-fpm7.4:phpphp-fpm7.4:php 的网络并入 nginx,并通过修改 nginx 的 /etc/hosts,把域名 php 映射成 127.0.0.1,让 nginx 通过 php:9000 访问 php-fpm。

注:因为是nginx去 link PHP 所以,在启动Nginx的时候,PHP要先启动起来

启动如下图所示:

编写 index.php 文件 查看phpinfo();

vim /root/nginx/www/index.php

访问路由 http://192.168.174.130:10000/index.php

Docker - composer

PHP 怎么能少的了 composer 呢

拉取镜像: docker pull composer

创建目录

在主机创建一个目录,用以保存 composer 的配置和缓存文件

mkdir ~/composer

编辑本地配置

# 编辑文件
vim ~/.bashrc

# 输入以下内容,根据实际情况修改相应目录
composer () {
        tty=
        tty -s && tty=--tty
        docker run $tty --interactive --rm --user $(id -u):$(id -g) --volume ~/composer:/tmp --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro  --volume $(pwd):/app composer "$@"
}

生效配置

source ~/.bashrc

使用

在当前用户下,可以全局使用,composer install

PHP开发环境搭建

PHP开发环境搭建

可以使用 docker 搭建一个 LNMP 镜像包,这个不做介绍

说明:MySQL:8.0.22、PHP:7.4.11、Redis:6.0.8、Nginx:1.19.3、Laravel:6.19.1

使用容器间的互联功能

准备目录文件

mkdir /www
mkdir -p ~/nginx/www ~/nginx/conf ~/nginx/conf/conf.d ~/nginx/logs
mkdir -p ~/redis/data ~/redis/conf
mkdir ~/composer
mkdir ~/mysql

早期方式,不太建议

一、启动 Redis

docker run --name redis -d -p 6379:6379 -v /root/redis/data:/data -v /root/redis/conf/redis.conf:/etc/redis/redis.conf redis redis-server /etc/redis/redis.conf --appendonly yes

二、启动 MySQL

docker run --name mysql -it -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /root/mysql:/var/lib/mysql mysql

三、启动 php-fpm 并关联 redis + mysql

docker run --name php-fpm74 -p 9000:9000 -v /root/nginx/www/:/www -d --link mysql:mysql --link redis:redis php:7.4-fpm

四、启动 Nginx

docker run -d -p 80:80 --name nginx  --mount type=bind,source=/root/nginx/www,target=/usr/share/nginx/html  --mount type=bind,source=/root/nginx/logs,target=/var/log/nginx  --mount type=bind,source=/root/nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf  --mount type=bind,source=/root/nginx/conf/conf.d,target=/etc/nginx/conf.d --link php-fpm74:php nginx

验证

拉项目

改 Nginx 配置文件

这个配置文件特别需要注意,具体请看 --network 中的配置文件注释部分

重启 Nginx 容器

路由访问

互联二: --network

新建一个网络 docker network create -d bridge my-net

  • -d 指定网络类型,有 bridge(一般选这个)、 overlay(用于 Swarm mode)

一、启动 Redis

docker run --name redis -d -p 6379:6379 --network my-net -v /root/redis/data:/data -v /root/redis/conf/redis.conf:/etc/redis/redis.conf redis redis-server /etc/redis/redis.conf --appendonly yes

二、启动 MySQL

docker run --name mysql -it -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /root/mysql:/var/lib/mysql --network my-net mysql

三、启动 php-fpm

docker run --name php -p 9000:9000 -v /www:/www -d --network my-net php:7.4-fpm

四、启动 Nginx

docker run -d -p 80:80 --name nginx --mount type=bind,source=/root/nginx/www,target=/usr/share/nginx/html --mount type=bind,source=/root/nginx/logs,target=/var/log/nginx --mount type=bind,source=/root/nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf --mount type=bind,source=/root/nginx/conf/conf.d,target=/etc/nginx/conf.d --network my-net nginx

验证

搞个简单的空框架项目下来

# 启动容器时,挂载的数据卷位置
cd /root/nginx/www

# 克隆一个项目下来,本地以空的 laravel6 为例
git clone xxxxxxxxxx.git

为了便于理解 /root/nginx/www 目录结构如下(将www作为项目目录):

修改 nginx 配置文件

挂载的时候,挂载了一个 /root/nginx/conf/nginx.conf 文件和一个 /root/nginx/conf/conf.d 目录

nginx.conf 文件内容如下,一般不用改

user  root;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

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;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

/root/nginx/conf/conf.d 目录下新建一个文件 test.com.conf 内容如下:

server {
    listen       80;

# 因为是在Windows上的VM里面运行的centOS,在CentOS上个运行的容器,所以这里我就搞了一个测试域名
    server_name  /www/php_demo/public;

# 因为将容器内的 /usr/share/nginx/html 目录映射到了宿主机的 /root/nginx/www 目录,所以在宿主机上对应的目录就是  /root/nginx/www/public
    root /usr/share/nginx/html/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    location / {
        index  index.php index.htm index.html;

        try_files $uri $uri/ /index.php?$query_string;
    }

    # 你会经常在日志中看到找不到 favicon.ico.php找不到的500报错
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ \.php$ {
        root /www/php_demo;

# 这个之前直接复制过来的,127.0.0.1:90000 这样写 Nginx 会报一个这样的错误:connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.174.1, server: test.com, request: "GET /index.php/asf HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "test.com"
# 报错意思就是连接不上 127.0.0.1:9000 ,经过查看(docker ps -a),启动php-fpm容器的IP是 172.18.0.4,所以这个地方做相应的调整,也可以直接使用容器名
        fastcgi_pass   php81:9000;
        fastcgi_index  index.php;

# 这个地方也要改成到 public 目录下才行
        fastcgi_param  SCRIPT_FILENAME /www/php_demo/public$fastcgi_script_name;
        include        fastcgi_params;
    }
}

重启 Nginx 容器

docker restart nginx

访问

可以看到 laravel 欢迎页,成功,优秀

修改 env 访问 mysqlredis

搞个路由,搞个控制器,验证一下即可,成功,完美

报错一:数据库错误 SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

百度查找的原因是说数据库版本为 8.0+ 密码认证机制改了等,做如下修改:

# 登陆MySQL
ALTER USER '用户名'@'主机地址' IDENTIFIED WITH mysql_native_password BY '密码';

FLUSH PRIVILEGES;

报错一:数据库错误 could not find driver

原因:没装扩展,装上即可 docker-php-ext-install pdo_mysql 可以查看docker安装PHP章节参考安装扩展

报错二:redis扩展没装

# 进入容器
docker exec -it php-fpm74 bash

# 执行安装命令
pecl install -o -f redis

# 添加扩展
cd /usr/local/etc/php
cp php.ini-production php.ini
echo "extension=redis.so" >> /usr/local/etc/php/php.ini

互联三: compose

Docker Compose

安装

# 下载二进制文件
curl -L "https://github.com/docker/compose/releases/download/1.27.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 赋予权限
sudo chmod +x /usr/local/bin/docker-compose

# 创建软链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 测试
docker-compose --version

使用

准备

创建 Dockerfile 文件

创建 docker-compose.yml

使用 Compose 命令构建和运行您的应用

yml 配置指令参考

YAML 入门教程

基本语法

  • 大小写敏感

  • 使用缩进表示层级关系

  • 缩进的空格数不重要,只要相同层级的元素左对齐即可

  • 不允许使用 tab,只允许空格

  • # 表示注释

数据类型

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)

  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)

  • 纯量(scalars):单个的、不可再分的值

对象

  • 使用 冒号 结构表示 key: value,冒号后面要加一个 空格

  • 使用 key:{key1: value1, key2: value2, ...}

  • 使用缩进

key: 
    child-key1: value1
    child-key2: value2
  • 使用 ? :,意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]
? 
    - complexkey1
    - complexkey2
: 
    - complexvalue1
    - complexvalue2

数组

- 开头的行表示构成一个数组:

- A
- B
- C

支持多维数组,可以使用行内表示:key: [value1, value2, ...]

子成员是一个数组:

-
 - A
 - B
 - C

一个相对复杂的例子:意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。

companies:
    -
        id: 1
        name: company1
        price: 200W
    -
        id: 2
        name: company2
        price: 500W

流式(flow)的方式表示:companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]

复合结构

数组和对象可以构成复合结构,例:

languages:
  - Ruby
  - Perl
  - Python 
websites:
  YAML: yaml.org 
  Ruby: ruby-lang.org 
  Python: python.org 
  Perl: use.perl.org

转换成 json 为:

{
  languages: [ 'Ruby', 'Perl', 'Python'],
  websites: {
    YAML: 'yaml.org',
    Ruby: 'ruby-lang.org',
    Python: 'python.org',
    Perl: 'use.perl.org'
  }
}

纯量

  • 字符串

  • 布尔值

  • 整数

  • 浮点数

  • NULL

  • 时间

  • 日期

例子:

boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
float:
    - 3.14
    - 6.8523015e+5  #可以使用科学计数法
int:
    - 123
    - 0b1010_0111_0100_1010_1110    #二进制表示
null:
    nodeName: 'node'
    parent: ~  #使用~表示null
string:
    - 哈哈
    - 'Hello world'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2    #字符串可以拆成多行,每一行会被转化成一个空格
date:
    - 2018-02-17    #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime: 
    -  2018-02-17T15:02:31+08:00    #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

引用

& 锚点和 * 别名,可以用来引用:

举例:

defaults: &defaults
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  <<: *defaults

test:
  database: myapp_test
  <<: *defaults

上述等价于:

defaults:
  adapter:  postgres
  host:     localhost

development:
  database: myapp_development
  adapter:  postgres
  host:     localhost

test:
  database: myapp_test
  adapter:  postgres
  host:     localhost

& 用来建立锚点(defaults),<< 表示合并到当前数据,* 用来引用锚点。

举例:

- &showell Steve
- Clark
- Brian
- Oren
- *showell

转为 JavaScript 代码如下:[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

Redis集群实操

参考如下链接

https://wiki.shuxiaoyuan.com/docs/show/228

LNMP实操

前置准备工作

创建网络

docker network create -d bridge my-net

创建映射目录

# Nginx、MySQL、Redis、PHP代码目录
mkdir -p ~/docker/lnmp/redis/conf
mkdir -p ~/docker/lnmp/redis/data
mkdir -p ~/docker/lnmp/mysql/data
mkdir -p ~/docker/lnmp/mysql/log
mkdir -p ~/docker/lnmp/mysql/conf.d
mkdir -p ~/docker/lnmp/nginx/conf
mkdir -p ~/docker/lnmp/nginx/conf/conf.d
mkdir -p ~/docker/lnmp/nginx/log
mkdir -p ~/docker/lnmp/nginx/www
mkdir -p /www

创建某些配置文件

redis 配置文件

vim ~/docker/lnmp/redis/conf/redis.conf

# 节点端口
port 6379

# 密码
requirepass 123456

# 保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
protected-mode no

# 是否以守护线程的方式启动(后台启动),默认 no;
daemonize no

# 是否开启 AOF 持久化模式,默认 no;
appendonly yes

mysql 配置文件

vim ~/docker/lnmp/mysql/conf.d/my.cnf

###### [client]配置模块 ######
[client]
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock

###### [mysql]配置模块 ######
[mysql]
# 设置MySQL客户端默认字符集
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock

###### [mysqld]配置模块 ######
[mysqld]
port=3306
user=mysql
# 设置sql模式 sql_mode模式引起的分组查询出现*this is incompatible with sql_mode=only_full_group_by,这里最好剔除ONLY_FULL_GROUP_BY
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server-id = 1

# MySQL8 的密码认证插件 如果不设置低版本navicat无法连接
default_authentication_plugin=mysql_native_password

# 禁用符号链接以防止各种安全风险
symbolic-links=0

# 允许最大连接数
max_connections=1000

# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8mb4

# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB

# 0: 表名将按指定方式存储,并且比较区分大小写;
# 1: 表名以小写形式存储在磁盘上,比较不区分大小写;
lower_case_table_names=0

max_allowed_packet=16M 

# 设置时区
default-time_zone='+8:00'

nginx配置文件

vim ~/docker/lnmp/nginx/conf/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


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;

    # 更改成想要的大小
    client_max_body_size 20M;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80 default_server;
        # listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        location / {
            index index.html index.htm index.php;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}

nginx 测试文件

vim ~/docker/lnmp/nginx/www/index.html

<h1>Success</h1>
<h1>测试成功</h1>
<h1>SHUXIAOYUAN</h1>

Laravel 站点设置

server {
    listen       80;
    server_name  php-demo-local.com;

    root   /www/php_demo/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    location / {
        index  index.html index.htm index.php;

        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ \.php$ {
        root /www/php_demo;
        fastcgi_pass   blog:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/php_demo/public/$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

yml文件

vim ~/docker/lnmp/docker-compose.yml

# 定义服务,可以多个
services:
  redis:
    # 采用 image 指定镜像
    image: "redis:7"

    # 指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。
    container_name: redis

    # 指定容器退出后的重启策略为始终重启。
    # 该命令对保持服务始终运行十分有效,在生产环境中推荐配置为 always 或者 unless-stopped
    restart: always

    # 配置日志
    logging:
      # 日志驱动类型:json-file、syslog、none
      driver: "json-file"
      # 其他选项
      options:
        max-size: "1g"
    
    # 配置容器连接的网络
    network_mode: "my-net"

    # 暴露端口信息
    ports:
      - "6379:6379"
    
    # 数据卷所挂载路径设置
    volumes:
      - ~/docker/lnmp/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
      - ~/docker/lnmp/redis/data:/data

    # 覆盖容器启动后默认执行的命令。
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
  mysql:
    image: "mysql:8"
    container_name: mysql
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=123456 # root用户密码
    volumes:
      # 映射数据目录
      - ~/docker/lnmp/mysql/data:/var/lib/mysql
      # 映射日志
      - ~/docker/lnmp/mysql/log:/var/log/mysql
      # 映射配置目录
      - ~/docker/lnmp/mysql/conf.d:/etc/mysql/conf.d
      # 让容器的时钟与宿主机时钟同步,避免时间的问题,ro是read only的意思,就是只读。
      - /etc/localtime:/etc/localtime:ro
  nginx:
    image: "nginx:1.25"
    container_name: nginx
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    ports:
      - "80:80"
      - "443:443"

    # 解决容器的依赖、启动先后的问题,这里表示先启动php和redis,再启动nginx
    depends_on:
      - php
      - redis
    volumes:
      - ~/docker/lnmp/nginx/conf/conf.d:/etc/nginx/conf.d
      - ~/docker/lnmp/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ~/docker/lnmp/nginx/log:/var/log/nginx
      - ~/docker/lnmp/nginx/www:/usr/share/nginx/html
      - /www:/www
  php:
    image: "shuxiaoyuan/php:8.1.v5"
    container_name: php81
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "1g"
    network_mode: "my-net"
    volumes:
      - /www:/www

运行

docker compose up -d

Windows上Docker的使用

下载安装 docker 桌面

创建一个网络,让所有的容器之间可以相互通讯

docker network create -d bridge my-net

拉取各镜像

docker pull mysql:8
docker pull redis:7
docker pull nginx

启动各镜像

注意:挂载本地目录的时候,需要看容器内的具体目录是什么,比如redis容器是将数据写入到/data目录

# 启动 Redis
docker run --name redis -d -p 6379:6379 --network my-net --mount type=bind,source=D:\shuxiaoyuan\Docker\Redis\7,target=/data --mount type=bind,source=D:\shuxiaoyuan\Docker\Redis\7\redis.conf,target=/etc/redis/redis.conf redis:7 redis-server /etc/redis/redis.conf --appendonly yes

# 启动 MySQL
docker run --name mysql -it -d -p 3306:3306 --network my-net -e MYSQL_ROOT_PASSWORD=123456 --mount type=bind,source=D:\shuxiaoyuan\Docker\MySQL,target=/var/lib/mysql mysql:8

# 启动 PgSQL
docker run --name pgsql --network my-net -e POSTGRES_PASSWORD=123456 -p 5432:5432 --mount type=bind,source=D:\shuxiaoyuan\Docker\Yida\PgData,target=/var/lib/postgresql/data -d postgres:16

# 启动 Nginx
# 注意:nginx 容器和 PHP 容器记得都要挂载代码目录,不然 css、js等静态文件访问会 404
docker run -d -p 80:80 -p 443:443 --name nginx --network my-net --mount type=bind,source=D:\shuxiaoyuan\Docker\MI\Nginx\www,target=/usr/share/nginx/html --mount type=bind,source=D:\shuxiaoyuan\Docker\MI\Nginx\logs,target=/var/log/nginx --mount type=bind,source=D:\MyCode,target=/www --mount type=bind,source=D:\shuxiaoyuan\Docker\MI\Nginx\conf\nginx.conf,target=/etc/nginx/nginx.conf --mount type=bind,source=D:\shuxiaoyuan\Docker\MI\Nginx\conf\conf.d,target=/etc/nginx/conf.d nginx

# 启动 PHP 镜像
docker run --name php80 -d --network my-net --mount type=bind,source=D:\MyCode,target=/www shuxiaoyuan/php:8.0.28.v3

测试

本机用客户端连接 Redis、MySQL

查看网络

docker network inspect my-net

# 如下所示
[
    {
        "Name": "my-net",
        "Id": "294d948a918c81241e0c7e14bcbee7cd24f50a30fa6931914045cadd8f06d749",
        "Created": "2023-03-15T03:06:43.7510048Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2b2b018062aa22c4653c341d2a58ffb20cbd145e9575a2149c70e9c2defc4d18": {
                "Name": "mysql",
                "EndpointID": "7de0ad75f085532460d413fc18b66219765bfc6b8638a577807990329f487fd8",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "3408aeef4eec4fb61d64db292c59e2758141214fe5e69b21e17b8319ab06622f": {
                "Name": "ecshop",
                "EndpointID": "4c6414ca0fc2c48e3a388b9d4cf566eab39a170a9983549fbee3dfeff0d75a0a",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "a590f2231f13116322cc1edc79aff07aa70a8d364d17dbb45d4c6b0fd98a3ade": {
                "Name": "redis",
                "EndpointID": "6de904bffdb25b6543b423c816d811f554643d509fe5abb24842c01635508c02",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

容器内互 ping

docker exec -it redis /bin/bash
ping 172.18.0.3

# 若提示么有找到 ping 命令,请自行安装
apt-get update && apt install iputils-ping

代码连接 Redis、MySQL

修改项目的 env 配置即可,看是否能链接成功

打包镜像

打包镜像

D:\MyCode\Docker\ 目录下新建了一个 shop 文件 写入如下内容

FROM registry.cn-hangzhou.aliyuncs.com/shopex_company/ecshopex-php:ecx-7.4.32-fpm-alpine3.16

RUN set -eux \
    && apk --no-cache add ca-certificates tzdata \
           --repository https://mirrors.aliyun.com/alpine/v3.9/main/ \
    && apk add supervisor \
    && apk add nginx \
    && apk add vim \
    && mkdir /etc/supervisor.d/ \
    && mkdir -p /data/httpd \
    && cd /data/httpd \
    && wget http://shuxiaoyuan-201812.oss-cn-shanghai.aliyuncs.com/data/20230306/license.zl \
    && cd /usr/bin \
    && wget http://shuxiaoyuan-201812.oss-cn-shanghai.aliyuncs.com/data/20230306/entrypoint.sh \
    && chmod +x /usr/bin/entrypoint.sh \
    && echo "swoole_license_files=/data/httpd/license.zl" >> /usr/local/etc/php/conf.d/docker-php-ext-swoole_loader74.ini

进入相应目录,运行打包命令

cd D:\MyCode\Docker
docker build -f shop . -t sxy_shop:v2
解决Windows上docker卡成翔的问题

采用将文件直接放入 wsl2 的 Ubuntu-22.04 系统中,减少文件转换

项目文件,可以放在 Windows 上任意位置,通过phpstorn自动部署的方式,将项目传输到 WSL2 里面去,也可以直接将项目放在 WSL2 里面,PHPStorm 直接打开WSL2里面的项目,以下主要说如何通过通过自动部署的方式

1、应用商店安装 Ubuntu

2、进入 Ubuntu

或者

进行各种配置,权限,用户,配置 SSH 等

# 如果遇到权限问题,请加 sudo
docker ps
sudo mkdir /www
cd /www
sudo vim test.php
cd
ssh-keygen -t ed25519 -C "yida_ubuntu"
cd .ssh/
cat id_ed25519.pub
sudo chmod -R 777 www/

# 也可以不用克隆项目,因为是本地开发,所以用 IDE 直接同步即可
git clone git@gitee.com:shuxiaoyuan/php_demo.git

3、打开 docker 的 WSL integration

如果没有显示,那么可能需要先执行第三步,进入 Ubuntu 系统进行初始化等工作

4、查看刚创建的文件

打开 Windows 资源管理器,输入 \\wsl.localhost\Ubuntu-22.04\www 即可看到刚刚创建的文件

5、拉取项目

cd /www
git clone git@gitee.com:shuxiaoyuan/php_demo.git

6、运行 Docker 挂载项目

注意:以下 PHP 和 Nginx 容器都是在进入 Ubuntu 系统内操作的,其他容器根据你的需求来

# 创建网络
docker network create -d bridge my-net

# 运行 PHP 容器
docker run --name php81 -d --network my-net --mount type=bind,source=/www,target=/www shuxiaoyuan/php:8.1.v2

创建 nginx 挂载文件夹

cd
mkdir -p docker/Nginx
cd docker/Nginx
mkdir -p www logs conf
vim www/index.html # 随便写点啥

找个 nginx.conf 配置文件,不想找就抄下面的vim conf/nginx.conf

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


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;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80 default_server;
        # listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        location / {
            index index.html index.htm index.php;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}

搞个站点文件vim conf/conf.d/php-demo-local.com.conf

server {
    listen        80;
    server_name  php-demo-local.com;
    root   /www/php_demo/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # 你会经常在日志中看到找不到 favicon.ico.php找不到的500报错
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        # root           /www/php_demo;
        fastcgi_pass   php80:9000;
        # fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME /www/php_demo/public$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

运行 Nginx 容器

# 根据你的实际情况来,这里为了方便观看拆成多行了,实际是一行
docker run
-dp 80:80
--name nginx
--network my-net
--mount type=bind,source=/home/shuxiaoyuan/docker/Nginx/www,target=/usr/share/nginx/html
--mount type=bind,source=/home/shuxiaoyuan/docker/Nginx/logs,target=/var/log/nginx
--mount type=bind,source=/home/shuxiaoyuan/docker/Nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf
--mount type=bind,source=/home/shuxiaoyuan/docker/Nginx/conf/conf.d,target=/etc/nginx/conf.d
--mount type=bind,source=/www,target=/www
nginx:1.25.2

7、配置 phpstorm 自动同步

如果重写文件或文件夹失败,可能需要设置相应权限

缺点

  1. 本方案采用的是 IDE 自动同步代码,所以最好勾上“本地删除后删除远程文件”,这样切换分支的时候,就可以自动同步代码

如果嫌弃麻烦,可以直接打开

报错

报错1

The current user is not a member of the docker-users group.
To continue, update the group membership for the current user.

解决:https://learn.microsoft.com/zh-cn/troubleshoot/developer/visualstudio/ide/troubleshooting-docker-errors

  • 在“开始”菜单中,打开 “计算机管理”。
  • 展开 “本地用户和组”,然后选择“ 组”。
  • 找到 docker-users 组,右键单击并选择“ 添加到组”。
  • 添加一个或多个用户帐户。
  • 注销并重新登录,使这些更改生效。
DockerFile文件

PHP

php:8.0.28-fpm

v0.01 初始化

安装软件:Vim Cron Composer

安装扩展:

bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xlswriter
xml
xmlreader
xmlwriter
zip
zlib

DockerFile文件:php_8.0.28.v0.01

FROM php:8.0.28-fpm

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v0.0.1" \
      org.opencontainers.image.description="第一个基础测试版本,安装软件有:vim,cron,composer、安装的扩展有:"

WORKDIR /www

# 构建 xlswriter 扩展,根据自身需要替换版本号
ENV XLSWRITER_VERSION 1.5.1

RUN set -eux \
    && apt-get update \
    && apt-get install -y vim \
    && apt-get install -y cron \
    && apt-get install -y zlib1g-dev \
    && apt-get install -y libzip-dev \
    && apt-get install -y libpng-dev \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install zip \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install gd \
    && pecl install -o -f redis \
    && pecl install -o -f xlswriter \
    && docker-php-ext-enable redis\
    && docker-php-ext-enable xlswriter\
    && cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
    && cd /root \

    # 编译安装 xlswriter
    # && curl -fsSL "https://pecl.php.net/get/xlswriter-${XLSWRITER_VERSION}.tgz" -o xlswriter.tgz \
    # && mkdir -p /tmp/xlswriter \
    # && tar -xf xlswriter.tgz -C /tmp/xlswriter --strip-components=1 \
    # && rm xlswriter.tgz \
    # && cd /tmp/xlswriter \
    # && phpize \
    # && ./configure --enable-reader \
    # && make \
    # && make install

    && php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \
    && php composer-setup.php \
    && mv composer.phar /usr/local/bin/composer \
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
    && service cron start \

    && rm -rf /tmp/pear \
    && service cron start \
    && echo "alias ls='ls --color=auto'" >> /root/.bashrc \
    && echo "alias ll='ls --color=auto -la'" >> /root/.bashrc

# 编译安装后不会自动加载,需要配置到 php.ini 文件里面
# RUN echo "extension=xlswriter.so" > /usr/local/etc/php/php.ini

编译 DockerFile 文件 docker build -f .\php_8.0.28.v0.0.1 -t shuxiaoyuan/php:8.0.28.v0.01 .

运行容器,查看个软件和扩展是否安装成功: docker run --name test -d shuxiaoyuan/php:8.0.28.v0.01

v0.02 添加 mcrypt 扩展

添加扩展:mcrypt

DockerFile文件:php_8.0.28.v0.02

FROM shuxiaoyuan/php:8.0.28.v0.01

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v0.0.2" \
      org.opencontainers.image.description="添加 mcrypt 扩展"

WORKDIR /www

RUN set -eux \
    && apt-get update \
    && apt-get install -y libmcrypt-dev \
    && pecl install mcrypt \
    && docker-php-ext-enable mcrypt

编译 DockerFile 文件

docker build -f .\php_8.0.28.v0.02 -t shuxiaoyuan/php:8.0.28.v0.02 .

安装后的扩展列表

[PHP Modules]
bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mcrypt
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xlswriter
xml
xmlreader
xmlwriter
zip
zlib

[Zend Modules]

php:8.1-fpm

v1

FROM php:8.1-fpm

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v1" \
      org.opencontainers.image.description="第一个基础版本"

WORKDIR /www

RUN set -eux \
    && apt-get update \
    && apt-get install -y zlib1g-dev \
    && apt-get install -y libzip-dev \
    && apt-get install -y libpng-dev \
    && apt-get install -y libmcrypt-dev \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install zip \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install gd \
    && cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
    && echo "alias ls='ls --color=auto'" >> /root/.bashrc \
    && echo "alias ll='ls --color=auto -la'" >> /root/.bashrc


# 安装 vim
RUN apt-get install -y vim


# 安装 cron
RUN apt-get install -y cron \
&& service cron start


# 安装 Redis
RUN pecl install -o -f redis \
&& docker-php-ext-enable redis


# 安装 mcrypt
RUN pecl install -o -f mcrypt \
&& docker-php-ext-enable mcrypt


# 安装 xlswriter
RUN pecl install -o -f xlswriter \
&& docker-php-ext-enable xlswriter


# 安装 composer
RUN php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \
&& php composer-setup.php \
&& mv composer.phar /usr/local/bin/composer \
&& composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
&& rm -rf composer-setup.php


# 清理临时文件
RUN rm -rf /tmp/pear

v2: 安装 pdo_pgsql 扩展

FROM shuxiaoyuan/php:8.1.v1

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v2" \
      org.opencontainers.image.description="添加 pgsql"

WORKDIR /www

# 安装PostgreSQL客户端库
RUN apt-get update \
&& apt-get install -y libpq-dev


# 安装PHP的PDO PostgreSQL扩展
RUN docker-php-ext-install pdo_pgsql


# 清理临时文件
RUN rm -rf /tmp/pear

v3: 安装 wkhtmltopdf

FROM shuxiaoyuan/php:8.1.v2

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v3" \
      org.opencontainers.image.description="安装 wkhtmltoxpdf"

WORKDIR /www

# 安装 wkhtmltopdf
# 安装路径: /usr/bin/wkhtmltopdf /usr/bin/wkhtmltoimage
RUN set -eux \
    && apt-get update \
    && apt-get install -y wkhtmltopdf \
    && apt-get install -y wget

# 安装中文字体
RUN cd /usr/share/fonts \
    && wget https://beego-gz-study-1252088954.cos.ap-guangzhou.myqcloud.com/test/simsun.ttc

# 清理临时文件
RUN rm -rf /tmp/pear
PHP

php的官方镜像分为三个分支:下面我都是以 fpm 分支为基础镜像

  • cli :没有开启CGI,也就是不能运行fpm,只能运行命令行。

  • fpm :开启了CGI,可以用来运行web服务也可以运行cli命令。

  • zts :开启了线程安全的版本。

7.4 简单安装扩展版

  • php:7.4-fpm/v1.4
FROM php:7.4-fpm

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
    org.opencontainers.image.url="https://www.shuxiaoyuan.com" \
    org.opencontainers.image.documentation="https://book.shuxiaoyuan.com/show/3" \
    org.opencontainers.image.version="v1.4" \
    org.opencontainers.image.description="基于官方 php:7.4-fpm 镜像,制作个人开发的 php 7.4 环境,本次版本v1.4,主要新增如下功能:安装扩展pdo_mysql;bcmath;gd;zip;redis、安装git、安装composer"


WORKDIR /www

RUN set -eux \
    && apt-get update \
    && apt-get install -y git \
    && apt-get install -y zlib1g-dev \
    && apt-get install -y libzip-dev \
    && apt-get install -y libpng-dev \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install zip \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install gd \
    && pecl install -o -f redis \
    && docker-php-ext-enable redis\
    && rm -rf /tmp/pear \
    && cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
    && php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \
    && php composer-setup.php \
    && mv composer.phar /usr/local/bin/composer \
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
    && rm -rf composer-setup.php

编译:docker build -f /root/dockerfile/php74_v1.4 -t shuxiaoyuan/php74:v1.4 .

运行:docker run --name php74 -d shuxiaoyuan/php74:v1.4 进入容器,检查软件和扩展是否都安装成功 安装完成后的扩展如下:

bcmath、Core、ctype、curl、date、dom、fileinfo、filter、ftp、gd、hash、iconv、json、libxml、mbstring、mysqlnd、openssl、pcre、PDO、pdo_mysql、pdo_sqlite、Phar、posix、readline、redis、Reflection、session、SimpleXML、sodium、SPL、sqlite3、standard、tokenizer、xml、xmlreader、xmlwriter、zip、zlib

登录:docker login -u shuxiaoyuan 上传:docker push shuxiaoyuan/php74:v1.4

shuxiaoyuan/php74 安装 crontab + vim

FROM shuxiaoyuan/php74:v1.4

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.url="https://www.shuxiaoyuan.com" \
      org.opencontainers.image.documentation="https://book.shuxiaoyuan.com/show/3" \
      org.opencontainers.image.version="v1.5" \
      org.opencontainers.image.description="基于官方 php:7.4-fpm 镜像,制作个人开发的 php 7.4 环境,本次版本v1.5,主要新增如下功能:安装crontab、vim"

RUN set -eux \
    && apt-get update  \
    && apt-get install vim -y \
    && apt-get install cron -y \
    && service cron start \
    && echo "alias ls='ls --color=auto'" >> /root/.bashrc \
    && echo "alias ll='ls --color=auto -la'" >> /root/.bashrc

编译、运行、测试、上传

测试 crontab 是否正常工作

# 编写一个简单的demo,就是将123 输出到一个指定的文件中
* * * * * echo "123" >> /www/php_demo/storage/logs/crontab.log

注意:在 docker 容器中,php-fpm 的运行用户是 www-data,php要带全路径

crontab -e -uwww-data

* * * * * cd /www/php_demo && /usr/local/bin/php artisan schedule:run >> /www/php_demo/storage/logs/crontab-www-data.log

php8.0 简单扩展版

php:8.0.28-fpm

FROM php:8.0.28-fpm

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.url="https://www.shuxiaoyuan.com" \
      org.opencontainers.image.documentation="https://book.shuxiaoyuan.com/show/3" \
      org.opencontainers.image.version="v2" \
      org.opencontainers.image.description="基于官方 php:8.0.28-fpm 镜像,制作个人开发的 php 8.0 环境,本次版本v2,主要新增如下功能:安装扩展pdo_mysql;bcmath;gd;zip;redis、安装git、安装composer"

WORKDIR /www

RUN set -eux \
    && apt-get update \
    && apt-get install -y git \
    && apt-get install -y zlib1g-dev \
    && apt-get install -y libzip-dev \
    && apt-get install -y libpng-dev \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install zip \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install gd \
    && pecl install -o -f redis \
    && rm -rf /tmp/pear \
    && docker-php-ext-enable redis\
    && cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini \
    && php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" \
    && php composer-setup.php \
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
    && mv composer.phar /usr/local/bin/composer

编译:docker build -f /root/dockerfile/php8.0.28_v2 -t shuxiaoyuan/php:8.0.28.v2 .

运行、进入容器、查看扩展和软件,安装后的扩展列表

bcmath、Core、ctype、curl、date、dom、fileinfo、filter、ftp、gd、hash、iconv、json、libxml、mbstring、mysqlnd、openssl、pcre、PDO、pdo_mysql、pdo_sqlite、Phar、posix、readline、redis、Reflection、session、SimpleXML、sodium、SPL、sqlite3、standard、tokenizer、xml、xmlreader、xmlwriter、zip、zlib

8.0.2 添加其他

FROM shuxiaoyuan/php:8.0.28.v1

LABEL org.opencontainers.image.authors="Xiaoyuan Shu <sxy@shuxiaoyuan.com>;<shuxiaoyuan520@gmail.com>" \
      org.opencontainers.image.version="v3" \
      org.opencontainers.image.description="要新增如下功能:安装 vim 和 crontab"

WORKDIR /www

RUN set -eux \
    && apt-get update  \
    && apt-get install vim -y \
    && apt-get install cron -y \
    && service cron start \
    && echo "alias ls='ls --color=auto'" >> /root/.bashrc \
    && echo "alias ll='ls --color=auto -la'" >> /root/.bashrc
安装PHP扩展

安装 amqp 扩展

1、安装 rabbitmq-c

https://github.com/alanxz/rabbitmq-c

wget https://github.com/alanxz/rabbitmq-c/releases/download/v0.8.0/rabbitmq-c-0.8.0.tar.gz

tar zxf rabbitmq-c-0.8.0.tar.gz

cd rabbitmq-c-0.8.0

./configure --prefix=/usr/local/rabbitmq-c-0.8.0

make && make install

2、安装 amqp 扩展

方式一:pecl安装

pecl install amqp

# 提示需要输入 rabbitmq-c 安装路径
Set the path to librabbitmq install prefix [autodetect] : /usr/local/rabbitmq-c-0.7.1

# 报错
fatal error: amqp_ssl_socket.h: No such file or directory

将 rabbitmq-c-0.7.1/librabbitmq/amqp_ssl_socket.h 文件复制到 amqp 目录内,因为是临时文件,安装报错后就没了,所以采用第二种方式

方式二:源码安装

去官网寻找合适版本,不同的PHP版本对应不同的版本:https://pecl.php.net/package/amqp

wget https://pecl.php.net/get/amqp-1.11.0.tgz

tar -zxvf amqp-1.11.0.tgz

cd amqp-1.11.0

phpize

注意此处的路径,请自行进行相应的修改
./configure --with-php-config=/usr/local/bin/php-config --with-amqp --with-librabbitmq-dir=/usr/local/rabbitmq-c-0.8.0

make && make install

如果 make 时报错如下:fatal error: amqp_ssl_socket.h: No such file or directory
那么将相应的 amqp_ssl_socket.h 文件复制到 amqp 目录下即可
cp /root/rabbitmq-c-0.8.0/librabbitmq/amqp_ssl_socket.h /root/amqp-1.11.0/


成功后会告诉你扩展路径
Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20200930/

编辑 php.ini 文件,加入相应扩展名
vim /usr/local/etc/php/php.ini

extension=amqp.so

保存后查看是扩展否安装成功: php -m | grep amqp
Nginx

主要是解决一个 https 的证书问题

# 安装 certbot
sudo apt-get update
sudo apt-get install certbot -y

# 运行命令获取证书, xxxxx.com 为你的域名
# 会验证你的域名,就是确保是你的域名
# 验证的方式很简单,就是在你的域名下放置一个校验文件
certbot certonly --standalone -d xxxxx.com

# 提示需要输入你的邮箱,续签通知
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): sxy@shuxiaoyuan.com

# 接受条款
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

# 接受广告
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

# 开始生成证书
Account registered.
Requesting a certificate for demo-dev.shuxiaoyuan.com
Performing the following challenges:
http-01 challenge for demo-dev.shuxiaoyuan.com
Cleaning up challenges

# 报错了,哈哈哈,因为 80 端口被占用了
Problem binding to port 80: Could not bind to IPv4 or IPv6.


# 验证成功后,Certbot 将颁发 SSL 证书并将其保存在 /etc/letsencrypt/live/xxxxx.com 目录下

# 后续就是在 nginx 的配置文件里面配置上你的证书即可

证书续签问题

RabbitMq
# 拉取镜像
docker pull rabbitmq:management


# 运行镜像
docker run -id --name=rabbitmq --network my-net  --mount type=bind,source=D:\MyCode\Docker\mount\RabbitMq,target=/var/lib/rabbitmq -p 15672:15672 -p 15673:5672 -e RABBITMQ_DEFAULT_USER=shuxiaoyuan -e RABBITMQ_DEFAULT_PASS=123456 rabbitmq:management
推送镜像到第三方

阿里云

去阿里云开通相应服务 官网地址

1、登录

密码为开通服务时的密码

docker login --username=shu.xiaoyuan@163.com registry.cn-hangzhou.aliyuncs.com

2、制作

docker tag 605c77e624dd registry.cn-hangzhou.aliyuncs.com/shuxiaoyuan/nginx:1.21.5

3、推送 docker push registry.cn-hangzhou.aliyuncs.com/shuxiaoyuan/nginx:1.21.5

4、拉取镜像

docker pull registry.cn-hangzhou.aliyuncs.com/shuxiaoyuan/nginx:1.21.5

如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-hangzhou.aliyuncs.com 作为Registry的域名登录。

腾讯云