【web开发】docker中的数据库
注:自从开始使用docker,部署方面的事情就简单多了。使用docker构建的数据库容器不用直接安装,开启后就可以使用,也比以前方便很多。下面将一些要点记录下来。
下面的例子使用以下环境:
- 系统(即host):CentOS Linux release 7.4.1708
- docker:Docker version 17.12.0-ce, build c97c6d6
- 数据库:MariaDB 5.5
启动数据库
MariaDB是MySQL的一个分支,使用起来基本上没有什么差别。在docker hub中有该数据库的官方镜像,使用下面的简单命令就可以开启一个数据库容器,开启后可以利用IP+端口号的方式访问该数据库。
[belter@localhost ~]$ docker run -d -p : -v ~/mdbdata/mdb55:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=admin --name mdb55 mariadb:5.5
c7f2cd8ed93de8ab8ab58171c375e83fb2659c2a1cdab2ec79c264cb78b1e131
[belter@localhost ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7f2cd8ed93d mariadb:5.5 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:->/tcp mdb55
- 使用第1行的命令,就可以开启一个数据库容器,主要参数:
-d: 表示detach,后台运行并打印container ID;
-p: 端口,3301:3306表示将容器中的3306端口公开给host的3301端口;
-v: 表示volume,用来设置数据文件存放的位置,~/mdbdata/mdb55:/var/lib/mysql表示将host中当前用户home目录下的文件夹"mdbdata/mdb55"挂载于容器中的/var/lib/mysql目录,这样即使容器被删除,数据文件还是可以保留;
-e: 表示environment,用来设置用户及密码等环境变量,MYSQL_ROOT_PASSWORD=admin表示将root的密码设置为admin(只在第一次登陆数据库时使用);
--name: 表示容器的名称,例如现在这个数据库容器的名称为mdb55
命令的最后是镜像的名称,mariadb:5.5表示MariaDB-5.5
- 第2行是返回的容器编号
- 第3行的命令用来查看当前运行的容器列表,第4-5行可以看到刚刚启动的数据库容器的基本信息
此外可以使用下面的命令查看全部容器的状态(包括已经停止运行的容器),以及删除容器
[belter@localhost ~]$ docker ps -a # 查看所有的容器
[belter@localhost ~]$ docker rm 92a1bcd89578 # 删除ID为92a1bcd89578的容器
Mariadb在docker hub中的官方网站,以及build镜像mariadb:5.5的Dockerfile文件。
下面测试一下刚启动的数据库容器的连接:
[belter@localhost ~]$ mysql -u root -padmin -h 127.0.0.1 -P3301
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is
Server version: 5.5.-MariaDB-~trusty mariadb.org binary distribution Copyright (c) , , Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
现在已经可以正常连接该数据库了(由于这里使用了host中的mysql命令,因此需要先安装mysql才能使用)。
- 注意-padmin和-P3301之间没有空格,一个表示user的密码,另一个表示连接的端口号;
- -h: 表示需要连接的数据库的IP地址,这里连接的是本地IP+3301端口,host中的3301端口是访问数据库容器中3306端口的入口;
上面使用host中的mysql来连接容器中的数据库,需要先在本地安装mysql(或MariaDB)。此外也可以直接进入容器内部连接该数据库:
[belter@localhost ~]$ docker exec -it c7f2cd8ed93d /bin/bash
root@c7f2cd8ed93d:/# mysql -u root -padmin -h 127.0.0.1 -P3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is
Server version: 5.5.-MariaDB-~trusty mariadb.org binary distribution Copyright (c) , , Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
- 使用第1行命令,进入刚才启动的数据库容器(ID为c7f2cd8ed93d)的bash;
- 进入容器后,使用第2行命令连接容器内部的数据库,此时使用的端口号是3306.
注:退出数据库和容器都可以使用"exit;"
为了测试修改密码以及数据文件的重用,在数据库中做了以下修改:修改root的密码,创建一个新的数据库"test"并在该数据库中创建一个表"table1"
# 修改root的密码为admin1,并更新权限列表
SET PASSWORD FOR 'root'@'%' = PASSWORD('admin1');
FLUSH PRIVILEGES; # 创建数据库test,并在该数据库中创建表table1
CREATE DATABASE test;
CREATE TABLE table1(
col1 VARCHAR(50),
col2 VARCHAR(50)
); # 在表table1中插入两行记录
INSERT INTO table1(col1, col2) VALUES(1, 'Belter'), (2, 'Merry Christmas');
数据文件可以直接复制到另一个文件夹来备份(所有者修改为ods:ssh_keys,与原数据文件相同)
使用docker-compose配置数据库
利用上面的方法可以快速开启一个数据库容器,连接后就可以使用。但是配置的参数都写在命令行中不利于后面的维护。此时可以使用docker-compose来保存配置文件:
对于数据库来说,主要需要以下几方面的配置:用户及密码,数据文件存放的位置,端口,字符集。
下面是我的配置文件:
version: '2.2' services:
db:
image: mariadb:5.5
restart: always
environment:
- MYSQL_HOST=localhost
- MYSQL_PORT=3306 # port in container
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
- MYSQL_USER=belter
- TZ=Asia/Shanghai
volumes:
- ~/mdbdata/mdb55:/var/lib/mysql
ports:
- 3303:3306
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --skip-character-set-client-handshake
更多关于docker-compose.yml文件的介绍,可参考我的上一篇博客:使用docker搭建数据分析环境
- environment是对容器内部来说的,第10行设置为"%"表示允许使用root远程连接数据库,第11行指定了MYSQL_USER直接访问的数据库,MYSQL_USER需要手动添加;
- 修改完root密码后,就不需要在environment中指定MYSQL_ROOT_PASSWORD这一参数了,该参数相当于指定了数据库初始化时的root密码;
- 第19-21行,配置了数据库的字符集,更多可参考link1, link2
- host的端口换成3303
停止之前运行的容器,并使用docker-compose启动上面配置好的容器:
[belter@localhost mariadb]$ docker stop c7f2cd8ed93d
c7f2cd8ed93d
[belter@localhost mariadb]$ docker-compose up -d
Creating network "mariadb_default" with the default driver
Creating mariadb_db_1 ... done
[belter@localhost mariadb]$ docker-compose logs
Attaching to mariadb_db_1
db_1 | :: [Note] mysqld (mysqld 5.5.-MariaDB-~trusty) starting as process ...
db_1 | :: InnoDB: The InnoDB memory heap is disabled
db_1 | :: InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1 | :: InnoDB: Compressed tables use zlib 1.2.
db_1 | :: InnoDB: Using Linux native AIO
db_1 | :: InnoDB: Initializing buffer pool, size = 256.0M
db_1 | :: InnoDB: Completed initialization of buffer pool
db_1 | :: InnoDB: highest supported file format is Barracuda.
db_1 | :: InnoDB: Waiting for the background threads to start
db_1 | :: Percona XtraDB (http://www.percona.com) 5.5.59-MariaDB-38.11 started; log sequence number 1601918
db_1 | :: [Note] Plugin 'FEEDBACK' is disabled.
db_1 | :: [Note] Server socket created on IP: '0.0.0.0'.
db_1 | :: [Warning] 'proxies_priv' entry '@ root@c7f2cd8ed93d' ignored in --skip-name-resolve mode.
db_1 | :: [Note] Event Scheduler: Loaded events
db_1 | :: [Note] mysqld: ready for connections.
db_1 | Version: '5.5.60-MariaDB-1~trusty' socket: '/var/run/mysqld/mysqld.sock' port: mariadb.org binary distribution
- 第1行停止了之前的容器(停止后3301端口就无法访问了);
- 第3行从docker-compose启动了新的数据库容器;
- 第6行查看容器开启之后的日志,第22行显示数据库已经可以正常连接.
使用上面的方法,连接host的3303端口:
[xiongxin@localhost mariadb]$ mysql -u root -padmin1 -h 127.0.0.1 -P3303
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is
Server version: 5.5.-MariaDB-~trusty mariadb.org binary distribution Copyright (c) , , Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
rows in set (0.00 sec) MariaDB [(none)]> select * from test.table1;
+------+-----------------+
| col1 | col2 |
+------+-----------------+
| | Belter |
| | Merry Christmas |
+------+-----------------+
rows in set (0.00 sec) MariaDB [(none)]>
可以正常连接,且之前的数据还可以查询到。
在另一个容器中连接数据库
创建另一个文件夹"query-db",从另外一个镜像上开启一个新的容器,如果这个容器需要连接上面的数据库容器该怎么办呢?
下面使用的镜像可以在我的docker hub中下载到:django_py35_new,更多关于这个问题的讨论可以参考Stack OverFlow。
直接使用host的IP(127.0.0.1)和本地的端口(3303)无法连接。这时候需要使用docker内部自己建立的网络将这两个容器连接起来。
在该文件夹下创建如下docker-compose.yml文件:
version: '2.2' services:
djangoApp:
image: onlybelter/django_py35_new
# restart: on-failure
command: python3 query_db.py
working_dir: /code
volumes:
- ./code:/code
- /etc/localtime:/etc/localtime:ro
environment:
- PYTHONUNBUFFERED=1 networks:
default:
external:
name: mariadb_default
并且在该文件夹下创建新的文件夹"code",并将名为query_db.py的文件放到code文件夹,该文件内的代码如下:
import MySQLdb
import time def q_db():
db = MySQLdb.connect(host='db', port=3306, user='root',
passwd='admin1', db='test')
try:
q_queue = """SELECT a.col2 FROM table1 AS a;"""
with db.cursor() as cursor:
cursor.execute(query=q_queue)
one_queue = cursor.fetchall()
print(one_queue[0], one_queue[1], '\n')
except Exception as e:
print(e)
finally:
db.close() while 1:
q_db()
time.sleep(5)
- 在上面的docker配置文件中的第7行,会执行code文件夹中名为"query_db.py"的Python脚本,即上面所示的Python代码;
- 配置文件的第15-18行,添加了数据库容器中默认网络的名称"mariadb_default"作为自己的一个扩展网络(一般由文件夹的名称+"_default");
整体的目录结构如下:
mariadb # 数据库容器所在的文件夹
docker-compose.yml
query-db # 查询数据库的另一个容器所在的文件夹
docker-compose.yml
code # code文件夹
query_db.py
可以使用下面的命令来查看当前正在运行的容器所属的网络(通常名称为外部的文件夹名称加一个"_default"后缀):
[belter@localhost query-db]$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1d35e7fb797c bridge bridge local
8a2336ca7bcc djangopy35_default bridge local
8d044b04d49f mariadb_default bridge local
由于扩展网络的连接,上面的Python代码会查询之前建立的数据库容器(名称为db,配置文件中service的名称)的3306端口(docker的内网),然后输出数据库中的内容:
[belter@localhost query-db]$ docker-compose up
Starting querydb_djangoApp_1 ... done
Attaching to querydb_djangoApp_1
djangoApp_1 | ('Belter',) ('Merry Christmas',)
djangoApp_1 |
djangoApp_1 | ('Belter',) ('Merry Christmas',)
djangoApp_1 |
djangoApp_1 | ('Belter',) ('Merry Christmas',)
djangoApp_1 |
Merry Christmas!
Reference
https://mariadb.com/resources/blog/mariadb-and-docker-use-cases-part-1/
https://stackoverflow.com/a/47980388/2803344
【web开发】docker中的数据库的更多相关文章
- 基于gin的golang web开发:访问mysql数据库
web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动.直接使用驱动提供的API就要写很多样板代码.你可以找到很多扩展包这里介绍的是jmoiron/sqlx.另外还有 ...
- 在Docker中体验数据库之MySql
在上一篇在Docker中体验数据库之Mongodb之后,这次记录一下在docker中安装mysql.过程要比Mongodb麻烦一点…… 参考网址: https://dev.mysql.com/doc/ ...
- web开发技术中Servlet技术的概述
1.servlet是什么:servlet是一个位于服务器端的java应用程序它可以像jsp一样,直接输出信息 servlet类必须继承HttpServlet类,否则,不能称为serlvet servl ...
- 在Docker中体验数据库之Microsoft SQL Server
前面记录了一下在docker中体验mongodb和mysql.今天记录一下mssql……其实早就体验了,就是没有记录,前几天看了一下2019的一些新闻,很喜欢Polybase这个特性,想体验一把,可惜 ...
- docker中的数据库
注:自从开始使用docker,部署方面的事情就简单多了.使用docker构建的数据库容器不用直接安装,开启后就可以使用,也比以前方便很多.下面将一些要点记录下来. 下面的例子使用以下环境: - 系 ...
- docker中mysql数据库
在docker中安装mysql数据库,直接上代码,pull 并run 补充20190809=============== 如果要挂载数据库实现数据持久化到本地的时候,会出现权限问题,这个原因是: 在执 ...
- 在Docker中体验数据库之Mongodb
本文记录一下,在docker中安装Mongodb的过程. 环境:物理机 ubuntu18.04 因为环境变了,我在一台物理机上直接安装了ubuntu(非虚拟机和双系统),制作U盘镜像.安装参考:htt ...
- Java Web开发Tomcat中三种部署项目的方法
第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: <Context path="/hello" docBase ...
- python web开发-flask连接sqlite数据库
在之前的文章中我们介绍了如何在centOS中安装sqlite数据库. Sqlite安装完成后,本节就用flask来连接和操作sqlite数据库. 1. 数据准备 先在sqlite3中创建一 ...
随机推荐
- py3.0第四天 函数,生成器迭代器等
1.列表生成式,迭代器&生成器 孩子,我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1,你怎么实现?你可能会想到2种方式 > ...
- 初入TensorFlow————配置TensorFlow
能看到这说明你对python已经有一定的了解了,因此很多基础直接跳过. 一.TensorFlow环境配置: TensorFlow的环境配置在网上很多的教程都是用anaconda的方式,但是很容易出现冲 ...
- Spring Boot中使用Lombok消除POJO类模板代码
首先,要让IDE支持Lombok,这里以idea为例进行介绍. 点击项目的“File”-—>"settings"—>"Plugins",在marke ...
- python 实现rsa 的加密解密存读取(PEM格式证书)【转发】
来源:CSDN 原文:https://blog.csdn.net/sjt1996/article/details/83377800
- 安装完Ubuntu后通过shell脚本一键安装软件
安装完Ubuntu后通过shell脚本一键安装软件 以下代码中#是单行注释 :<<! ! 是多行注释. 运行的时候需要把多行注释去掉. 比如把以下代码保存为install.sh, 那么在终 ...
- JS入门经典第二章总结
document:在对网页编写脚本时,我们使用document对象代表网页.要引用一个属性,只需在document对象后加一个“.”号,然后再加上要引用的属性名. alert():该函数弹出一个消息框 ...
- MySQL的计算时间差
一.MySQL计算两个日期的时间差 TIMESTAMPDIFF(DAY, datetime1, datetime2); 第一个参数为比较类型,有day, month, year, hour等: 第二个 ...
- drawable内存管理
图片对象: drawable bitmap etc.图片对象在Android上该缓存吗?什么时候缓存?怎么缓存?缓存后使用时怎么取出?怎么销毁?什么时候销毁? bitmap对象(new出来的) :需要 ...
- Tinkoff Challenge - Final Round (Codeforces Round #414, rated, Div. 1 + Div. 2)
A: 思路:就是找b,c之前有多个s[i] 代码: #include<stdio.h>#define ll long longusing namespace std;ll a,b,c;in ...
- 包建强的培训课程(1):Android App企业级开发
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...