我的docker隨筆17:使用docker-compose啓動MySQL、Redis和Mongo

一、背景

有網友諮詢用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:6379redis--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官方鏡像及說明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章