Docker实践

Motivation

这个bluelog运行在云服务器上,明年这时候就差不多过期了,还没想好到时候迁移到哪里,就想着用docker打包一下,方便之后使用。同时bluelog原来使用python2.7 + pipenv构件开发环境的。准备升级到python3 + pip + docker的环境。

准备工作

下载docker,参考相关文档。在bluelog的根目录下创建Dockerfile。

创建docker volume持久化保存mysql的数据,创建network用于两个容器通信

╰─$ docker volume create bluelog_mysql                                      1 ↵
bluelog_mysql
╰─$ docker volume create bluelog_mysql_config
bluelog_mysql_config
╰─$ docker network create bluelog_mysqlnet
1845be4225056f8994881d90476a8188e7ca44097801901b8fada5dce0f131c5

启动mysql容器,创建数据库awesome

$ docker run --rm -d -v bluelog_mysql:/var/lib/bluelog_mysql \
-v bluelog_mysql_config:/etc/mysql -p 3306:3306 \
--network bluelog_mysqlnet \
--name mysqldb \
-e MYSQL_ROOT_PASSWORD=dbpass \
mysql

╰─$ docker ps                                                               1 ↵
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
cf7a578b689e        mysql               "docker-entrypoint.s…"   23 seconds ago      Up 22 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   bluelogdb

$ docker exec -it mysqldb mysql -u root -p                              1 ↵
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.

mysql> create database awesome default character set utf8mb4 collate utf8mb4_unicode_ci;
Query OK, 1 row affected (0.01 sec)

测试使用的bluelog/.env文件部分内容:

FLASK_CONFIG=production
DATABASE_URL=mysql://root:dbpass@mysqldb/awesome?charset=utf8mb4

Dockerfile内容

FROM python:3.8-slim-buster

WORKDIR /bluelog

COPY requirements.txt requirements.txt

RUN pip3 install -r requirements.txt
RUN pip3 install flask-whooshee
RUN pip3 install pymysql
RUN pip3 install cryptography

COPY . .

CMD ["python3", "-m" , "flask", "run", "--host=0.0.0.0"] # 开放给外部可见

根据Dockerfile构件bluelog-docker镜像

$ docker build --tag bluelog-docker .

启动bluelog-app容器

$ docker run \                                                                      
--rm -d \   # --rm: Automatically remove the container when it exits. -d: Run container in background and print container ID
--network bluelog_mysqlnet \ # 使用的网络
--name bluelog-app \
-p 8000:5000 \ # 本机端口:容器端口
bluelog-docker

发现了一些bug,ModuleNotFoundError: No module named 'MySQLdb',参照解决,使用pymysql作为数据库接口

进入bluelog-app容器中使用flask命令初始化博客

$ docker exec -it bluelog-app bash                                                                                                  1 ↵
root@e7bdaaa29534:/bluelog# ls
Dockerfile  Pipfile       Procfile          README.md   bluelog  migrations        tests    whooshee
LICENSE     Pipfile.lock  Procfile.windows  blogdb.sql  logs     requirements.txt  uploads  wsgi.py
root@e7bdaaa29534:/bluelog# flask init --username admin --password 123
Initializing the database...
Creating the temporary administrator account...
Creating the default category...
Done.

即可在localhost:8000端口访问博客

使用docker-compose自动化

在bluelog目录下创建docker-compose.yml

version: "3.7"

services:
  app:
    build:
     context: .  # The app service uses an image that’s built from the Dockerfile in the current directory. 
    ports:
    - "8000:5000"
    volumes:
    - ./:/bluelog

  mysqldb:  # 这个名称就是要被连接的hostname
    image: mysql
    ports:
    - 3306:3306
    environment:
    - MYSQL_ROOT_PASSWORD=dbpass
    volumes:
    - bluelog_mysql:/var/lib/mysql
    - bluelog_mysql_config:/etc/mysql

volumes:  # 这两个volumes是之前用docker volume创建的
  bluelog_mysql:
  bluelog_mysql_config:

启动

$ docker-compose up

重复之前的操作,对接mysql container,创建数据库awesome

mysql> create database awesome default character set utf8mb4 collate utf8mb4_unicode_ci;
Query OK, 1 row affected (0.01 sec)

对接bluelog-container,初始化博客

# flask init --username admin --password 123
Initializing the database...
Creating the temporary administrator account...
Creating the default category...
Done.

访问localhost:8000 bluelog Done!

迁移数据

将本地文件复制到docker容器中

在mysql容器中创建数据库blogdb(对应这台服务器上的),同时更改.env文件的URL

sugar@ubuntuServer:~$ mysqldump -u root -p --opt blogdb > blogdb.sql
Enter password: 
# 本机
$ scp sugar@118.178.94.244:/path/to/blogdb.sql . 
# 复制到docker mysql container中
$ docker cp blogdb.sql bluelog_mysqldb_1:/blogdb.sql
$ docker exec -it bluelog_mysqldb_1 bash
# 导入到数据库中
# 注意可能只能单独启一个mysql,不启动bluelog
root@db14eda59ac1:/# mysql -u root -p blogdb < blogdb.sql 

$ docker-compose up