常用的中间件服务使用 docker/ podman 进行部署。
Docker Hub 上可以搜索并查看镜像以及版本,对应的镜像有部署说明。 (2023 年算是彻底寄了,必须使用魔法或者镜像站搜索了)。所有的容器镜像均由用户上传,因此对应的文档说明非常重要。
本文使用的服务镜像大部分基于官方提供,较为通用。如果各位少侠使用非官方打包的镜像,配置映射目录、文件什么的需要参照文档。
单独运行示例
单独运行非常简单,这里只列举一个需要容器内部配置文件的 MySQL 示例。docker/podman 在使用 -v 映射时的本地目录需要先行手动创建,否则会报错;在映射文件时,若文件不存在则会报错并自动创建一个与文件同名的目录。
所以通常需要先有一个默认的配置文件,方便我们在本机修改使用,而不是进入容器内部修改。
一般两种方式
- 本机目录中自己新建文件并复制粘贴内容(或者直接下载官方相同版本的软件,然后上传配置文件)
- 复制容器的默认文件到本机
毫无疑问,第二种最方便,有现成的容器为什么不用?
复制配置文件并启动
# 创建所需目录
mkdir -p /data/server/mysql/conf && mkdir -p /data/server/mysql/data
cd /data/server/mysql
# 直接启动一个简单的基础镜像(只是用来复制配置文件,用完就删除),镜像不存在会自动 pull
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.36
# 复制容器的配置文件到当前目录下的 conf/ 中
docker cp mysql:/etc/my.cnf conf/
# 删除镜像
docker stop mysql && docker rm mysql
# 使用自定义的配置文件启动MySQL并且在启动时创建一个数据库
docker run -d -p 3306:3306 --name mysql8 \
-v /data/server/mysql/conf:/etc/mysql/conf.d \
-v /data/server/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_ROOT_HOST='%' \
-v MYSQL_DATABASE=要创建的数据库名称 \
--restart=always mysql:8.0.36
如果需要导入之前的数据库备份文件到此容器中,由于指定的数据卷映射,可直接复制到 /data/server/mysql/data 中,然后重启 docker 容器即可。
上面示例中从运行、复制文件到停止删除临时镜像有四步。如果有很多的文件需要 cp,那就使用这种方式;但如果只有一个文件,还是有点儿麻烦的。docker/podman 提供了一种简单且快速的从镜像内部复制文件的方式,复制后启动的容器会自行删除。
# 语法一般为
# docker/podman run --rm --entrypoint=cat <镜像名称>:<镜像版本> <镜像内部的文件路径> > <本机文件路径>
docker run --rm --entrypoint=cat library/mysql:8.0.45 /etc/my.cnf > /data/server/mysql/conf/my.cnf
# podman
podman run --rm --entrypoint=cat library/nginx:1.29.5 /etc/nginx/nginx.conf >/data/server/nginx/nginx.conf
这样简单了很多,不需要再找配置文件的示例或者对应服务版本的下载链接。
-e MYSQL_ROOT_PASSWORD选项必须指定!为了安全!如果可以访问 docker hub 官网的话,MySQL 镜像文档中有说明示例。 参考:https://dev.mysql.com/doc/refman/8.0/en/docker-mysql-more-topics.html#docker-optimized-installation
远程连接
启动完成后,进入 MySQL 的 bash 环境: docker exec -it mysql8 mysql -u root -p,执行下面几个条命令开启远程连接:
use mysql;
# MySQL8.0 之前授权远程连接,password 根据自身情况修改
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
# 刷新权限
FLUSH PRIVILEGES;
# MySQL8.0 之后授权远程连接
# 方式一
create user 'dev'@'%' identified by '123456';
grant all privileges on *.* to 'dev'@'%' with grant option;
flush privileges;
# 方式二
grant all privileges on *.* to 'root'@'%' with grant option;
flush privileges;
如果本机使用可视化工具(dbeaver、navicat)连接出现以下错误:Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’,请使用 127.0.0.1 连接,不要使用 localhost。
从mysql容器中备份数据
# 导出单张表的数据(含结构)
docker exec -it [contain_id/contain_name] mysqldump [db_name] -u[username] -p[password] --tables [table_name] > /home/user/xxx.sql
# 导出单张表的数据(不含结构)
docker exec -it [contain_id/contain_name] mysqldump -t [db_name] -u[username] -p[password] --tables [table_name] > /home/user/xxx.sql
# 导出数据库数据(含结构)
docker exec -it [contain_id/contain_name] mysqldump -u[username] -p[password] [db_name] > /home/user/xxx.sql
# 导出数据库数据(不含结构)
docker exec -it [contain_id/contain_name] mysqldump -t -u[username] -p[password] [db_name] > /home/user/xxx.sql
# 只导出整个数据库的结构
docker exec -it [contain_id/contain_name] mysqldump --opt -d -u[username] -p[password] [db_name] > /home/user/xxx.sql
常用服务的 compose 脚本
compose 脚本的作用就是实现快速部署!不然每次都要 run,比较麻烦。以下 compose 需要自行修改相关信息。
version: '3'
services:
mysql:
# 使用镜像
image: docker.io/mysql:8.0.45
# 镜像名称
container_name: mysql
# docker/podman 启动时直接启动该容器
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root_password
# 加上 command 开启 root 用户的远程连接
MYSQL_ROOT_HOST: '%'
# 运行时创建一个数据库
MYSQL_DATABASE: database_name
# 网络
networks:
- app-net
# 挂载数据卷
volumes:
- BASE_PATH/mysql8/data:/var/lib/mysql
- BASE_PATH/mysql8/log:/var/log/mysql
- BASE_PATH/mysql8/conf.d:/etc/mysql/conf.d
command: --bind-address=0.0.0.0
redis:
image: docker.io/redis:7.4.1
container_name: redis
restart: always
ports:
- "6379:6379"
environment:
REDIS_PASSWORD: 123456
networks:
- app-net
volumes:
- BASE_PATH/redis/data:/data
- BASE_PATH/redis/conf.d:/etc/redis
- BASE_PATH/redis/log:/var/log/redis
valkey:
image: valkey/valkey:8.1.5
container_name: valkey
restart: always
ports:
- "16379:6379"
environment:
VALKEY_REQUIREPASS: 123456
networks:
- app-net
volumes:
- BASE_PATH/valkey/data:/data
- BASE_PATH/valkey/conf:/usr/local/etc/valkey
- BASE_PATH/valkey/logs:/var/log/valkey
nginx:
image: docker.io/library/nginx:1.27
container_name: nginx
restart: always
ports:
- "80:80"
volumes:
- BASE_PATH/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- BASE_PATH/nginx/html:/usr/share/nginx/html
- BASE_PATH/nginx/conf.d:/etc/nginx/conf.d
- BASE_PATH/nginx/logs:/var/log/nginx
networks:
- app-net
minio:
image: minio/minio:RELEASE.2025-04-08T15-41-24Z
container_name: minio
restart: always
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9001:9001"
- "9000:9000"
volumes:
- BASE_PATH/minio/data:/data
command: server /data --console-address ":9001"
networks:
app-net:
driver: bridge
常用命令
# podman
podman-compose -f docker-compose.yml up -d
# docker
docker-compose -f docker-compose.yml up -d
# 单独部署 compose 中的某个服务
podman-compose -f docker-compose.yml up -d nginx

说些什么吧!