Flask+MySQL+Redis的Docker配置


Docker配置了好多天,昨天晚上終於把碎遮項目的Docker打包完成了,后面會繼續完善項目代碼,把穩定版本打包后推送到DockerHub上。

網上關於Docker配置的文章很多,但大部分都是復制粘貼,讓人不明所以。。在上面我浪費了好多時間。

Docker的下載和安裝就不再贅述,直接開始配置環節,我使用的是docker-compose.yml,docker compose 在 Docker 容器運用中具有很大的學習意義,docker compose 是一個整合發布應用的利器。而使用 docker compose 時,懂得如何編排 docker compose 配置文件是很重要的。

要使用docker-compose,首先要把每個部分的Dockerfile寫好,然后在docker-compose.yml文件中統一構建和啟動

docker-compose.yml配置文件詳解可以看:https://juejin.im/post/5aed4a776fb9a07a9918bb42

在我的項目結構是:

 

 雖然用到了redis,但是redis數據庫鏡像沒有啥需要配置的地方,所以就不用單獨再寫一個文件夾了。

docker-compose.yml內容為:

 

 

version: '3'
services:
  redis:
    image: "redis"
  mysql:
    image: mysql:5.7
    build: ./mysql
    environment:
      - MYSQL_DATABASE=SZheScan
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - "3306:3306"
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
  web:
    build: ./SZhe_Scan
    ports:
     - "5000:5000"
    links:
     - mysql:mysql
     - redis:redis
    depends_on:
     - mysql

  redis服務的鏡像基於容器鏡像redis啟動,無需要配置的地方,mysql服務基於容器鏡像mysql5.7進行啟動,包含mysql的dockerfile的文件夾是mysql文件夾,我們在build的時候要將其路徑寫出來,即./mysql,environment添加環境變量,可以看到添加了我們使用的數據庫名為SZheScan,(可能讀者會奇怪,數據庫初始化的時候應該是空的,應該什么時候創建數據庫及其里面的表文件?別急,繼續往下看)數據庫的密碼為root,最后是web服務,web服務的dockerfile在SZhe_Scan文件夾下,所以包含該路徑,端口號映射為外部的5000端口,links用於鏈接另一容器服務,如需要使用到另一容器的mysql服務。可以給出服務名和別名;也可以僅給出服務名,我們使用服務名和別名鏈接到兩個數據庫。事實上,在docker-compose啟動的時候,它會檢查你的links關系,從而依照應當有的順序來啟動,比如你需要先創建數據庫,再啟動Web服務。但是我這里又添加了一個depends_on來指定服務依賴mysql,可以省略depends_on。

然后我們需要在mysql和SZhe_Scan的文件夾下都編寫對應的Dockfile文件(如果你不止這些服務,比如還有nginx等,再多加一個nginx文件夾,同時在其中編寫其dockerfile和相關配置即可)

接着到mysql文件夾下:

 

 其中有三個文件,一個Dockerfile,是mysql啟動的時候會依照其配置啟動的,init文件夾下的文件是數據庫的初始化配置,mysqld.cnd是數據庫的另一個初始化配置,這里的文件位置放置不太好。

先看mysql的Dockerfile:

 

 

FROM mysql:5.7
ADD mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf
COPY ./init/init.sql /docker-entrypoint-initdb.d

  第一行是基於的鏡像,與docker-compose.yml里面的配置一樣,是mysql:5.7,第二行是將本地的配置文件復制到容器的配置文件中,第三行是將init文件夾中的初始化數據庫sql語句復制到/docker-entrypoint-initdb.d文件夾下。

重點講第三行:

基礎介紹參考自:https://blog.csdn.net/10km/article/details/79046864

摘錄一部分:

默認情況下,mysql鏡像創建的docker容器啟動時只是一個空的數據庫實例,為了簡化docker部署,我們需要
在docker創建mysql容器的時,數據庫和表已經自動建好,初始化數據也已自動錄入,也就是說容器啟動后數據庫就可用了。這就需要容器啟動時能自動執行sql腳本。

在mysql官方鏡像中提供了容器啟動時自動執行/docker-entrypoint-initdb.d文件夾下的腳本的功能(包括shell腳本和sql腳本)
docker-entrypoint.sh中下面這段代碼就是干這事兒的

        for f in /docker-entrypoint-initdb.d/*; do
            case "$f" in
                *.sh)     echo "$0: running $f"; . "$f" ;;
                *.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
                *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
                *)        echo "$0: ignoring $f" ;;
            esac
            echo
        done

  摘錄完畢。

簡單來說,在/docker-entrypoint-initdb.d文件夾下的,以.sh .sql .sql.gz結尾的文件,都會被自動執行,並且它執行的時間是在容器啟動的時候執行的,所以只要我們將數據庫需要初始化的sql文件或者bash文件復制進該文件夾,就能夠實現數據庫的庫,表,數據的初始化(比如說你要初始化一個管理員用戶之類的)

當然,如果你在這個文件夾下寫了很多個sql文件的話,它的執行順序是沒有保證的,但是網上也有很多的辦法進行處理,不在本篇博客的討論范圍之內。

init文件夾下的初始化sql文件為init.sql

 

 內容為:

CREATE DATABASE IF NOT EXISTS SZheScan default charset utf8 COLLATE utf8_general_ci;

use SZheScan;


CREATE TABLE `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(20) NOT NULL,
`username` varchar(50) NOT NULL,
`pw_hash` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `baseinfo` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`url` varchar(10) NOT NULL,
`status` varchar(4) NOT NULL,
`title` varchar(50),
`date` varchar(30) NOT NULL,
`responseheader` TEXT NOT NULL,
`Server` varchar(30),
`portserver` TEXT,
`sendir` TEXT,
`boolcheck` tinyint(1),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `ipinfo` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`baseinfoid` int(11) NOT NULL,
`bindingdomain` TEXT,
`sitestation` TEXT,
`CMessage` TEXT NOT NULL,
`ipaddr` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `domaininfo` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`baseinfoid` int(11) NOT NULL,
`subdomain` TEXT,
`whois` TEXT,
`bindingip` TEXT,
`sitestation` TEXT,
`recordinfo` varchar(100),
`domainaddr` varchar(100),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `buglist` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`oldurl` varchar(50),
`bugurl` varchar(50),
`bugname` varchar(100) NOT NULL,
`buggrade` varchar(7) NOT NULL,
`payload` varchar(100),
`bugdetail` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `poc` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`rule` TEXT,
`expression` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(20) NOT NULL,
`email` varchar(50) NOT NULL,
`date` DATE,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `invitationcode` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(36) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  做的事情是:創建一個SZheScan的數據庫,然后在其中創建所需要的表。

這里需要說明的是,flask應用我在編寫的時候,是使用migrate進行數據庫模型的遷移的,但是在網上沒有找到好的方法,將數據庫遷移模型直接在docker中創建其對應的表文件,只好出此下策,手動將表模型轉換成sql語句進行創建。

mysqld.cnf文件里面寫的是一些數據庫基本配置,網上很多博客都有,比較長,這里不再貼出。

最后到web服務SZhe_Scan文件夾:

 

 此文件夾下關注config.py和Dockerfile

config.py即你項目的配置文件。

 

 

import os
import redis
'''
配置文件:
    debug=true
    secret_key,session中的24位隨機鹽值
    MySQL數據庫配置
    數據庫名為scan_test_demo
        python3:https://blog.csdn.net/qq562029186/article/details/81325074
'''
DEBUG=True
SECRET_KEY=os.urandom(24)

HOSTNAME='mysql'
PORT='3306'
DATABASE='SZheScan'
USERNAME='root'
PASSWORD='root'
#SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@127.0.0.1/tushare?charset=utf8'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

SQLALCHEMY_TRACK_MODIFICATIONS=False

HOST = "redis"
redisPool = redis.ConnectionPool(host=HOST,port=6379, db=0, decode_responses=True)

  事實上這個在你編寫項目的時候已經寫好了,需要注意MySQL的HOSTNAME和redis的HOST。

相信讀者已經看出來了,這里的HOSTNAME不再是我們平常用的127.0.0.1,而變成了docker-compose.yml文件中mysql數據庫服務的名字:mysql,而redis的HOST也變成了docker-compose.yml中的redis數據庫服務的名字:redis

另外還需要將數據庫密碼修改為root,當然你docker-compose.yml里面的MySQL密碼是啥就寫啥,不要拘泥於此。MySQL數據庫也改為我們在init.sql數據庫初始文件中創建的數據庫名稱。

再看flask項目的Dockerfile文件

 

 

FROM python:3.6
WORKDIR /code
ENV FLASK_APP index.py
ENV FLASK_RUN_HOST 0.0.0.0
COPY . .
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["flask", "run"]

  本flask應用基於python3.6鏡像搭建,當然,對於鏡像的選擇也是一門學問,在滿足項目所有服務的前提下,基礎鏡像越小越好。

后面的配置這些就很簡單了,相信你也能夠看懂,這里為了pip下載快一點選擇了國內的鏡像網站,確實快了很多。還有如果你的flask服務是運行在服務器上,需要像我一樣,運行在0.0.0.0的IP地址上,ENV FLASK_RUN_HOST 0.0.0.0

所有都弄好了之后,回到最開始的位置:

 

 使用命令

docker-compose up

  就可以啟動服務啦。

也可以使用

docker-compose up -d

  將docker服務運行在后台。

如果還是運行不起來的話,也不要慌張,運行的時候會顯示報錯的原因,見招拆招就完事了,慢慢來會配置成功的。

 

參考鏈接:

https://www.cnblogs.com/luozx207/p/9935252.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM