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服務運行在后台。
如果還是運行不起來的話,也不要慌張,運行的時候會顯示報錯的原因,見招拆招就完事了,慢慢來會配置成功的。
參考鏈接: