一、背景
有网友咨询用docker-compose启动几个存储服务,这些服务包括了MySQL、Redis、Mongo。恰好笔记没做过这一方面,趁机会学习一下。
二、要求
需要启动的docker如下:
docker run -d --name myredis -v $PWD/data:/data -p 6378:6379 redis --appendonly yes
docker run --name=mysql -d -p 3306:3306 -e TZ=Asia/Shanghai \
--mount type=bind,source="$(PWD)"/data,target=/var/lib/mysql mysql/mysql-server:5.6 \
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci \
--explicit_defaults_for_timestamp=false
docker run -d --name mongo -p 27017:27017 mongo
分析如下:
除了常用的docker启动操作外,Redis需要添加持久化的配置,MySQL复杂很多,有时区,有挂载目录,有字符集编码配置。
三、实验
3.1 配置文件
先给出docker-compose文件,如下
version: '2'
services:
# 第一个容器 mysql
foomysql:
# 镜像名,如果不存在,则从网络下载,如果网络不存在,则会出错
image: mysql:5.6
# 容器名,在运行名称是唯一的
container_name: foomysql
restart: always # 如果容器运行出错,则重启容器
# 挂载数据卷
volumes:
- $PWD/mysqldata:/var/lib/mysql
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=latelee
- MYSQL_PASSWORD=123456
# 端口映射
ports:
- "3306:3306"
# 启动时执行的命令
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci', '--explicit_defaults_for_timestamp=false']
# 自定义的网络(见下[网络配置])
networks:
- foo-net
redis:
image: redis
container_name: fooredis
restart: always
volumes:
- $PWD/redisdata:/data
ports:
- "6379:6379"
command: ["redis-server", "--appendonly", "yes"]
networks:
- foo-net
mongo:
image: mongo
container_name: foomongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
networks:
- foo-net
mongo-express:
image: mongo-express
container_name: foomongo-express
restart: always
ports:
- 8081:8081
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
networks:
- foo-net
# 网络配置
networks:
foo-net: # foo-net是自定义的网络名称
driver: bridge # 桥接方式
挑几个要点说明如下:
1、挂载目录可以使用$PWD/
代替当前目录,也可以直接使用./
。当存在多个容器服务时,目录名称最好要有辨识度。
2、如果希望容器在启动的同时带有参数运行,则使用command
来指定。如command: ["redis-server", "--appendonly", "yes"]
,即等于redis-server --appendonly=yes
,对应到docker命令,是docker run -d --name myredis -v $PWD/data:/data -p 6378:6379 redis --appendonly yes
,注意,这句命令应该如此阅读:docker run -d --name myredis
、-v $PWD/data:/data
、-p 6378:6379
、redis
、--appendonly yes
。不能认为是redis --appendonly yes
。
3、mongo相关的环境变量,不能带前导的-
,即正确的是:
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root
不能是:
environment:
- MONGO_INITDB_ROOT_USERNAME: root
- MONGO_INITDB_ROOT_PASSWORD: root
否则会提示:
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.mongo.environment contains {"MONGO_INITDB_ROOT_USERNAME": "root"}, which is an invalid type, it should be a string
3.2 运行
使用docker-compose up
命令可以直接启动。如果不希望有输出信息,则使用docker-compose up -d
来启动。启动后,使用docker-compose ps
命令查看运行状态:
docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------
foomongo docker-entrypoint.sh mongod Up 27017/tcp
foomongo-express tini -- /docker-entrypoint ... Up 0.0.0.0:8081->8081/tcp
foomysql docker-entrypoint.sh mysql ... Up 0.0.0.0:3306->3306/tcp
fooredis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
从信息上看,已经可以正常运行了。
3.3 分析
这里重要关注一下MySQL的字符集设置是否正确。操作如下,注释见中文:
root@latelee:/home/latelee/docker/composefile/mysql_test# docker exec -it foomysql bash # 进入容器
root@61858ee65fd1:/# mysql -uroot -proot # 使用root进入MySQL
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.45 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show variables like '%character%'; # 查看字符集
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | utf8mb4 | ## !!!! 与配置的一致
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
mysql> show variables like 'collation%';
+----------------------+--------------------+
| Variable_name | Value |
+----------------------+--------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci | ## !!!! 与配置的一致
+----------------------+--------------------+
3 rows in set (0.00 sec)
mysql> select user from mysql.user; ## 查询用户
+---------+
| user |
+---------+
| latelee |
| root |
| root |
+---------+
3 rows in set (0.00 sec)
mysql> exit # 退出MySQL
Bye
root@61858ee65fd1:/# exit # 退出容器
exit
四、小结
针对网友的提问及本文的知识点,总结一下:
1、有些服务在启动时需要带参数,则可以在docker-compose文件中使用command
来指定参数。
2、如果这样做还不能达到目的,则要考虑自行重新构建docker镜像,在启动文件中添加参数。
3、不同的服务,其运行的进程名称不同,如MySQL服务名为mysqld
,Redis服务名为redis-server
,这些知识只能在日常积累,需要参考官方的说明文档,没有规律可遵——其实接触使用多了,也就熟悉了。如果一定要找规律,Linux系统,守护进程(或服务进程)名称是以d
结尾,d
表示daemon
。
4、官方镜像都带有介绍详细的说明。包括如何用docker启动,如果配置docker-compose等等。请自行参阅。
5、项目需要同时使用多个docker容器时,强烈建议使用docker-compose来管理。
6、实际项目不同,功能不同,参数亦不同,本文内容仅作为参考。
五、扩展
1、本文所述“docker-compose文件”,——包括作者日常交流,都是指“docker-compose.yml”这个文件。而“docker-compose”则是指docker-compose这个工具本身。
2、默认情况下,直接使用docker-compose up -d
命令启动即可。此时,docker-compose工具会在当前目录查找docker-compose.yml文件,并以目录名称作为工程名称。如果需要更改,则使用-f
来指定docker-compose文件,-p
指定工程名称。
3、docker-compose也有类似的
本文仅关注docker-compose的使用,对于MySQL、Redis、Mongo容器化未有深入研究,不作为实践的指导。如后续有机会,再进行研究。
附录
这是MySQL官方镜像及说明。
这是Redis官方镜像及说明。
这是Mongo官方镜像及说明。
这是mongo-express官方镜像及说明。
- 本文作者:李迟
- 版权声明:原创文章,版权归署名作者,转载建议注明出处(当然不注明亦可)。
- 本文链接:http://www.latelee.org/docker/docker-note-17-start-mysql-redis-mongo-using-docker-compose.html