Write the Code. Change the World.

12月 25

在 Docker Compose 中,command字段定义的命令是在容器启动时执行的默认命令。这意味着每次启动或重启容器时,都会执行command中定义的命令。

如果你希望在容器创建时执行一次特定的命令,而不是每次启动都执行,可以使用以下方法:

使用 entrypoint 脚本:

在 Docker Compose 中,你可以通过创建一个自定义的 entrypoint 脚本来实现在容器创建时执行一次的操作。entrypoint 脚本是在容器启动时执行的脚本,通常被用于初始化工作。

例如,你可以创建一个名为 entrypoint.sh 的脚本文件,然后在 docker-compose.yml 文件中引用它:

version: '3'

services:
  my-service:
    build:
      context: .
    entrypoint: /app/entrypoint.sh
    # 其他服务配置...

在 entrypoint.sh 中,你可以编写需要在容器创建时执行的命令,并在最后调用 exec "$@" 以保持容器正常运行:

#!/bin/bash

# 在容器创建时执行的命令
echo "Initialization command"

# 执行 CMD 中定义的命令
exec "$@"

这样,entrypoint.sh 中的命令将只在容器创建时执行一次。

将 command 配置在 Dockerfile 的 cmd 中

如果你只希望在容器创建时执行一次特定的命令,而不是每次启动都执行,可以将该命令直接包含在 Dockerfile 中。在 Dockerfile 的 CMD 指令中设置你希望执行的命令,而不在 docker-compose.yml 中的 command 中设置。

Dockerfile 示例:

FROM your-base-image

# 在容器创建时执行的命令
CMD ["your-initialization-command"]

# 其他 Dockerfile 配置...

在这种情况下,CMD 中定义的命令将只在容器创建时执行一次。

12月 25

给 mysql 数据库,常规来说得能访问 mysql 和 .sql 文件。对于 docker,可以通过映射或copy 的方式,将 .sql 语句弄到容器中,再执行 sql 语句。这种方式虽然可以实现,但感觉还是太麻烦了。还不如在宿主机,直接执行。 docker 提供了 exec 命令,可以用来搞定。

docker exec -i fa7 mysql -u zeipan -pzeipanpwd zeipan < /zeipan/conf/mysql/zeipan.sql

其中

  • -u zeipan 数据库用户名
  • -pzeipanpwd 数据库密码
  • zeipan 数据库库名
  • /zeipan/conf/mysql/zeipan.sql 宿主机的 sql 文件

这种方式虽然可以搞定。但是会报一个下边这样的警告。不让把密码直接弄到终端上。

mysql: [Warning] Using a password on the command line interface can be insecure.
12月 25

先查看

php

<?php
// 获取单个上传文件的最大大小
$uploadMaxFilesize = ini_get('upload_max_filesize');

// 获取 POST 请求的最大大小
$postMaxSize = ini_get('post_max_size');

echo "upload_max_filesize: $uploadMaxFilesize\n";
echo "post_max_size: $postMaxSize\n";
?>

也可以在 phpinfo() 函数中找到。

nginx

nginx -T | grep client_max_body_size

再修改

这里以 docker 来说。 如果没做宿主机配置文件和容器的映射就做一个,如果做了就修改配置文件。

假如这里没做映射。

在宿主机 compose.yaml 文件对应的目录下。新建 ./conf/php/php.ini 文件,加入以下配置。

# 单个上传文件的大小
upload_max_filesize = 50M

# 请求的最大大小
post_max_size = 50M

这里很灵活,只加想加的配置即可。

然后修改 compose.yaml 配置文件。

  php82:
    …
    volumes:
      - ${SOURCE_DIR}:/www/:rw
      - ${CONF_DIR}/php/php.ini/:/usr/local/etc/php/php.ini
      - ${LOG_DIR}/php82:/var/log/php

然后重启 php, 使得配置生效。

# 请记得 php82 是 compose.yaml 文件中,配置的 service 的名字。
docker-compose restart php82

这样就好了。

12月 21

有的时候就是这样,不给你网络,又要安装服务环境。这里是离线安装 docker 环境。传统 windows,下载好 exe 直接安装就好了,这里是 CentOS 7 、CentOS 8,也是类似的。

准备工作

  1. 找个可以联网的机器,下载 Docker RPM 包。

    • 访问 CentOS7 Docker CE Release 页面CentOS8 Docker CE Release 页面
    • 下载一下去 RPM 包(根据你的需求选择对应版本):
    • containerd.io-<VERSION>.rpm
    • docker-ce-<VERSION>.rpm
    • docker-ce-cli-<VERSION>.rpm
    • docker-ce-rootless-extras-<VERSION>.rpm
    • docker-buildx-plugin-<VERSION>.rpm
    • docker-ce-rootless-extras-<VERSION>.rpm
  2. 将下载的 RPM 包传输到离线机器。

  3. 下载 Docker Compose

    • Docker Compose GitHub Releases 。选择适应的版本。我喜欢用最新版,当前是 v2.23.2 点击进去,找到 linux 的版本。这里是 docker-compose-linux-x86_64

进去的链接如: https://github.com/docker/compose/releases/tag/v2.23.2
`

  1. 将下载的 Docker Compose 安装包传输到离线机器。

    安装

在离线机器上安装 RPM 包:

sudo yum install ./containerd.io-<VERSION>.rpm
sudo yum install ./docker-ce-<VERSION>.rpm ./docker-ce-cli-<VERSION>.rpm

启动 docker 服务

sudo systemctl start docker

将 Docker 添加到开机启动:

sudo systemctl enable docker

验证 Docker 安装

docker --version

解压 docker-compose 安装包

# 将 docker-compose 可执行文件移动到 /usr/bin 目录下
mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose

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

验证 Docker Compose 安装包

docker-compose --version
12月 19

操作

docker-compose build 

这会根据你的 Docker Compose 文件中的定义构建每个服务的镜像。

# 重命名镜像(其实,是搞了个新的引用)
docker tag old-image-name:old-tag new-image-name:new-tag

这个命令会创建一个新的标签为 new-image-name:new-tag 的镜像,并使其指向原始镜像 old-image-name:old-tag。 实际上,这并没有重命名原始镜像,而是在 Docker 中创建了一个新的标签,指向相同的镜像 ID。

确保 old-image-name:old-tag 存在于本地镜像仓库,否则 Docker 将会从远程仓库下载该镜像。

# 删除旧的引用(如果需要这么做的话)
docker rmi old-image-name:old-tag

请注意,docker rmi 只会删除标签,而不会删除镜像本身。如果这个标签是唯一指向该镜像的标签,那么整个镜像将被删除。

# 导出镜像
docker save -o output.tar image_name:tag
  • -o 参数指定输出的文件名。
  • image_name:tag 是要导出的 Docker 镜像的名称和标签。

其他 docker 环境使用。

docker load -i output.tar
12月 18

redis Connection refused

redis 容器自身,对 redis 的操作(连接使用)都 ok。 宿主机或其他容器连接 redis 总是报 Connection refused 错误。这里使用了 redis.conf。 将 redis.conf 的 bind 修改如下。

# 修改 redis.conf bind (默认是 bind 127.0.0.1 -::1)
bind 0.0.0.0 -::1

# 重启 redis
docker restart xxx(redis 容器 id)

重点

其他容器连接 redis 时,host 可以写 redis 这个和 docker-compose.yaml 中配置的 service 相对应。这个并不是容器名。连接 mysql 也可以这样。

services:
  mysql: 
    …
  redis:
    …

redis 其他配置

**docker-compose.yaml 中

# volume 配置 (其中,宿主机的 redis.conf 不存在,就会使用默认的 redis.conf)
# 这里主要三个方面:配置文件、数据、日志
    volumes:
    - ./conf/redis/redis.conf:/etc/redis/redis.conf
    - ${DATA_DIR}/redis:/data:rw
    - ${LOG_DIR}/redis:/logs
# 设置密码启动 redis**
# 123456 是 redis 密码
command: redis-server /etc/redis/redis.conf --requirepass "123456"

redis.conf 配置

配置项 描述
bind 指定本机网卡对应的IP地址,限制本机访问,默认 bind 127.0.0.1
daemonize 指定是否为守护进程方式运行,默认值为no
logfile 指定日志文件路径,默认值为 logfile ’ ', 默认为控制台打印,并没有日志文件生成
appendonly 是否开启持久化,默认值为 no

当 daemonize 设置了yes,表示redis在后台运行,当执行 docker-compose 执行启动 redis 进程时,docker 发现自己无事可做,容器自动结束,所以导致 redis 启动失败。

appendonly 为 yes 时,volume 需要配置 :rw,指定可写可读。

容器启动后设置密码

# 找到容器 id
docker ps

# 进入容器
docker exec -it xxx(redis 容器 id-前三位即可) bash

# 进入 redis
redis-cli

# redis 使用 (如果没设置密码,可以使用了。如果设置了密码,则提示 no auth)
redis get key

# 可以查看密码信息
config get requirepass

# 设置密码
config set requirepass yourPassword

# 输入密码
auth yourPassword

# 也可以在连接的时候带上密码
redic-cli -a yourPassword
12月 18

docker 网络

常用命令

# 显示网络
docker network ls

# 查看某个网络信息
docker network inspect xxx

# 删除网路
docker network rm xxx

# 批量删除网络
docker network rm $(docker network ls -q)

批量删除网络,有默认的三个网络是不能删除的。无论是批量删,还是单独删,都不可以。这三个网络是 bradge、host、none

NETWORK ID     NAME      DRIVER    SCOPE
a0457db48e55   bridge    bridge    local
f07f326dbd2b   host      host      local
437d811528b0   none      null      local