文章目錄
[一大渤、docker安裝MySql和Redis并啟動]
- [1. docker安裝]
- [2.docker啟動安裝的鏡像]
- [3. 查看docker啟動鏡像的時候所用的命令]
- [4. 停止和刪除鏡像容器]
- [5. 登陸和修改、提交鏡像]
[二、每個鏡像都有資源彼此獨(dú)立]
- [1. 如何查看docker里面container的ip]
- [2. docker創(chuàng)建的容器具有ip的原因和通信方式]
- [3. docker-compose編排容器并啟動]
- [4. 需要注意mysql和redis的ip修改]
[三辕翰、分離部署docker+nginx+uwsgi+mysql+redis]
- [1. 設(shè)計圖和項(xiàng)目路徑]
- [2. Dockerfile編寫]
[四咆瘟、uwsgi和docker爬坑]
- [1. 報錯invalid request block size: zxx...skip]
- [2. 啟動出現(xiàn)!!! no internal routing support, rebuild with pcre support !!!]
- [3. uwsgi提示 No such file or directory [core/utils.c line 3654]]
- [4. 提示failed to build: COPY failed: stat /var/lib/docker/tmp:no such file or directory]
- [5. mysql提示Failed to get stat for directory pointed out by --secure-file-priv]
- [6. Supplied value : /var/lib/mysql-files]
[五审轮、項(xiàng)目展示和項(xiàng)目地址]
[1. docker-compose編排成功后的截圖]
[2. 項(xiàng)目界面的截圖]
[3.寫在最后]
今天給大家?guī)砬昂蠖朔蛛x項(xiàng)目下的docker的部署和啟動,到最終的打包提交到dockerhub葫笼,以及爬坑記錄。旨在解決同道小伙伴們的痛點(diǎn)拗馒。
?剛學(xué)習(xí)docker路星,不足之處望請諒解,虛心接受大神指點(diǎn)诱桂,轉(zhuǎn)注出洋丐,誠謝~ 文末附項(xiàng)目效果展示和源碼地址呈昔。
一、docker安裝MySql和Redis并啟動
官網(wǎng)命令傳送門==>docker命令
1. docker安裝
- 查詢有哪些鏡像
$ docker search mysql
- 安裝指定的鏡像(在此之前請先配制好鏡像加速)
$ docker pull mysql:8.0.18
- 安裝默認(rèn)最新鏡像
$ docker pull mysql
# 或docker pull mysql:latest
同理安裝Redis
2. docker啟動安裝的鏡像
- 查詢本地安裝了的鏡像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 9b51d9275906 8 days ago 547MB
redis latest 7eed8df88d3b 2 weeks ago 98.2MB
- 啟動Mysql
# 將docker的mysql鏡像以守護(hù)進(jìn)程的方式創(chuàng)建實(shí)例mysql-demo(容器)
# 該實(shí)例的端口為3306對應(yīng)的宿主機(jī)上的12345友绝,初始化的數(shù)據(jù)庫密碼為5201020116.
# 也可以將宿主機(jī)的數(shù)據(jù)庫的配置掛載到mysql-demo對應(yīng)的位置
$ docker run -p 12345:3306 --name mysql-demo -e MYSQL_ROOT_PASSWORD=5201020116 -d mysql
因?yàn)槲业膍ysql的宿主機(jī)環(huán)境已經(jīng)安裝了堤尾,所以宿主機(jī)端口不能在用3306,改為了12345九榔。
- 啟動Redis
# 默認(rèn)redis容器里是沒有配置文件的(可在容器的/etc/查看redis.conf不存在)哀峻,因而需要在創(chuàng)建容器時映射進(jìn)來
# 設(shè)置密碼直接使用--requirepass "你的密碼"即可
# -i表示以交互模式運(yùn)行容器,-t表示重新分配偽終端, -d以守護(hù)進(jìn)程方式運(yùn)行; -v 表示映射文件哲泊;-p端口映射
$ docker run -itd --name redis-demo -v /etc/redis/redis.conf:/etc/redis.conf -p 9909:6379
--restart=always redis:latest redis-server --appendonly yes --requirepass "5201020116"
# 查看剛創(chuàng)建的容器的信息(截取部分)
$ docker ps -l
CONTAINER ID IMAGE CREATED STATUS PORTS NAMES
a83ef0e487e7 redis:latest 4 minutes ago Up 4 minutes 0.0.0.0:9909->6379/tcp redis-demo
# 再次進(jìn)入這個容器
$ docker exec -it a83ef0e487e7 /bin/bash
# 驗(yàn)證是否成功
root@a83ef0e487e7:/data# redis-cli
127.0.0.1:6379> auth 5201020116
OK
127.0.0.1:6379>
安裝啟動nginx同理剩蟀。
3. 查看docker啟動鏡像的時候所用的命令
$ docker ps -a --no-trunc
4. 停止和刪除鏡像容器
# 查看所有的容器
$ docker ps -a
# 停止/重啟/刪除容器 (已運(yùn)行需要先停止再刪除)
$ docker container stop/restart/rm a83ef0e487e7#容器ID
# 直接強(qiáng)制刪除
$ docker rm -f a83e#容器ID
# #刪除鏡像image,刪除前需要保證沒有container引用這個鏡像
$ docker rmi 9b51d9275906 #鏡像id
# 刪除所有鏡像
$ docker rmi $(docker images -q)
# 刪除所有沒有標(biāo)簽的鏡像
$ docker rmi $(docker images -q | awk '/^<none>/ { print $3 }')
5. 登陸和修改切威、提交鏡像
# 登錄dockerhub
$ docker login -u jackmin1314 # 你的dockerhub賬戶名
# 提交前切記修改鏡像為 賬戶名/鏡像名:tag
$ docker tag fe2880e71109 jackmin1314/spider_flask:latest
# 提交鏡像到本地
$ docker commit -a "jackmin1314 <1416@qq.com>" -m "this is test" 5bca95es95 myubuntu:v1
# 提交到遠(yuǎn)程dockerhub上面
$ docker push jackmin1314/spider_flask:latest
The push refers to repository [docker.io/jackmin1314/spider_redis]
a64d7a130512: Pushed
0554f8c96c61: Pushed
493605b7d1c9: Pushed
c742d444d284: Pushed
5216338b40a7: Mounted from library/alpine
latest: digest: sha256:0554f8c96c61....ea3c01 size: 1777
二育特、每個鏡像都有資源,彼此獨(dú)立
1. 如何查看docker里面container的ip
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 053e4f11df7a
因而想要讓docker內(nèi)部容器間訪問就需要通過ip來實(shí)現(xiàn)先朦。例如后端python項(xiàng)目和mysql交互缰冤。
2. docker創(chuàng)建的容器具有ip的原因
如下示意圖 :
- ?宿主機(jī)在安裝docker后,docker會在宿主機(jī)上生成一張docker虛擬網(wǎng)卡喳魏,docker網(wǎng)卡通過NAT的方式為每一個容器分配ip棉浸,容器同處于docker網(wǎng)段下,因而容器間通信刺彩,可以通過ip迷郑。
- 而容器和宿主機(jī)器通信,則是通過docker虛擬網(wǎng)卡進(jìn)行轉(zhuǎn)發(fā)路由创倔。
- 鏡像創(chuàng)建了容器后嗡害,容器名會對應(yīng)容器ip(在該容器的host有映射),因而可以通過容器名執(zhí)行相關(guān)操作.
三畦攘、前后端分離部署(docker+nginx+uwsgi+mysql+redis)
1. 設(shè)計圖和項(xiàng)目路徑
docker 的設(shè)計示意圖.(其中nginx的反向代理協(xié)議用的是wsgi霸妹,添加了include uwsgi_params;
,用了uwsgi_pass
因?yàn)楹笈_服務(wù)器用uwsgi知押;正常情況使用proxy_pass
即可)
項(xiàng)目文件 簡易說明
項(xiàng)目文件說明圖:
- BackServer/ ----后端源碼項(xiàng) 目
- vue_admin/ ---- 前端項(xiàng)目
- dist/ ---- 打包后線上部署的文件
- docker/ ---- mysql叹螟、redis、nginx的配置和dockerfile
- Dockerfile ---- BackServer托管uwsgi服務(wù)器的dockerfile
2. Dockerfile編寫
給出各個container的dockerfile,僅供參考台盯。
-
nginx的dockerfile
FROM nginx:latest LABEL auth=jackmin1314 maintainer="1416825008@qq.com" RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone # 移除nginx容器的default.conf文件首妖、nginx配置文件 RUN rm /etc/nginx/conf.d/default.conf RUN rm /etc/nginx/nginx.conf # 把主機(jī)的nginx.conf文件復(fù)制到nginx容器的/etc/nginx文件夾下 ADD ./docker/web/nginx.conf /etc/nginx/ # 容器間暴露8080端口.如果是云服務(wù)器部署,記得在安全組添加開放端口8080爷恳。 # 也可以在docker run -p指定具體的有缆,或者-P默認(rèn)expose暴露的端口 EXPOSE 8080 # CMD命令用于容器啟動時執(zhí)行,而不像RUN的鏡像構(gòu)建時候運(yùn)行 # 使用daemon off的方式將nginx運(yùn)行在前臺保證鏡像不退出 CMD ["nginx", "-g", "daemon off;"]
-
redis的dockerfile
FROM redis:latest WORKDIR /app/redis/ LABEL auth=jackmin1314 maintainer="1416825008@qq.com" RUN rm -rf /etc/redis/redis.conf RUN mkdir -p /var/log/redis/ RUN touch /var/log/redis/redis-server.log RUN chmod -R 777 /var/log/redis/ RUN chmod 777 /var/log/redis/redis-server.log COPY ./docker/redis/redis.conf . EXPOSE 6379 #CMD ["/usr/local/bin/redis-server", "/app/redis/redis.conf"]
-
mysql的dockerfile
FROM mysql:latest LABEL auth=jackmin1314 maintainer="1416825008@qq.com" RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone #WORKDIR /app # 拷貝mysql_spider的初始化數(shù)據(jù)庫和表的腳本 #COPY ./Mysql_Init_Script.sql /app COPY ./docker/mysql/Mysql_Init_Script.sql /docker-entrypoint-initdb.d/ RUN chmod -R 775 /docker-entrypoint-initdb.d RUN touch /var/lib/mysql-files RUN chmod -R 777 /var/lib/mysql-files
-
uwsgi的dockerfile
FROM alpine:latest LABEL auth=jackmin1314 maintainer="1416825008@qq.com" RUN mkdir -p /app/BackServer/ WORKDIR /app/BackServer COPY ./BackServer/ . RUN chmod -R 777 /app/BackServer/ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \ apk update && \ apk add python3 py3-pip python3-dev git gcc g++ linux-headers libstdc++ libffi-dev&& \ apk add uwsgi-python3 tzdata libxml2-dev libxslt-dev openssl-dev && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone && \ pip3 install --index-url=http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com -r requirements.txt && \ apk del py3-pip python3-dev git tzdata gcc g++ linux-headers && \ cd / && \ rm -rf ~/.cache/pip /var/cache/apk/* EXPOSE 9999 CMD ["uwsgi", "--ini", "uwsgi.ini"]
3. docker-compose編排容器并啟動
docker-compose.yml編寫啟動的順序(依賴關(guān)系)要注意 參考redis -> mysql -> uwsgi -> nginx
。例外棚壁,一旦指定了compose的某個service的上下文(主路徑),那么dockerfile的路徑將以compose設(shè)定為準(zhǔn)杯矩,而不是dockerfile所在目錄。
version: "3.7"
services:
redis:
hostname: spider-redis
# 根據(jù)BackServer/Config/config.py配置
container_name: spider-redis # 不指定則會系統(tǒng)自動分配名稱
restart: always # always表容器運(yùn)行發(fā)生錯誤時一直重啟
build:
context: ./
dockerfile: ./docker/redis/Dockerfile
#command: /usr/local/bin/redis-server /usr/local/etc/redis.conf
environment: # environment 一定要在command下面
- TZ=Asia/Shanghai
volumes:
- /etc/localtime:/etc/localtime:ro # 設(shè)置容器時區(qū)與宿主機(jī)保持一致
#- ./docker/redis/redis.conf:/usr/local/etc/redis.conf
privileged: true
ports:
- "6379:6379"
tty: true
mysql:
hostname: spider-mysql
container_name: spider-mysql
restart: always
build:
context: ./
dockerfile: ./docker/mysql/Dockerfile
#command:
environment:
# 這個根據(jù)項(xiàng)目BackServer的Config/config.py里面的設(shè)置對應(yīng)
- MYSQL_ROOT_PASSWORD=5201020116 # 配置數(shù)據(jù)庫的密碼
volumes:
# 初始化數(shù)據(jù)庫信息- ./docker/mysql/Mysql_Init_Script.sql:/docker-entrypoint-initdb.d/
- ./docker/mysql/my.cnf:/etc/mysql/my.cnf # 掛載配置文件-
- /etc/localtime:/etc/localtime:ro # 設(shè)置容器時區(qū)與宿主機(jī)保持一致
ports:
- "3306:3306"
flask:
hostname: spider-flask
container_name: spider-flask
restart: always
build: . # 執(zhí)行當(dāng)前的目錄下的dockerfile
# context: ./
# dockerfile: ./docker/uwsgi_flask/Dockerfile
volumes:
- /etc/localtime:/etc/localtime:ro # 設(shè)置容器時區(qū)與宿主機(jī)保持一致
ports:
- "9999:9999"
links:
- mysql
- redis
depends_on:
- mysql
- redis
nginx:
hostname: spider-nginx
container_name: spider-nginx
restart: always
build:
context: ./
dockerfile: ./docker/web/Dockerfile
ports:
- "8080:8080" # 根據(jù)nginx.conf配置
- "443:443"
volumes:
- ./dist/:/usr/share/nginx/html/dist
links:
- flask
depends_on:
- flask
4. 需要注意mysql和redis的ip修改
mysql和redis的ip不能是以前的localhost或者127.0.0.1.要改為容器名字
作為ip袖外,或者是容器的ip地址
史隆。
四、uwsgi和docker爬坑
1. 報錯invalid request block size: xxx...skip
這個是比較常見的曼验,問題出在請求的時候協(xié)議
和對應(yīng)uwsgi配置或啟動
不一致泌射,例如docker里面通過nginx容器訪問uwsgi需要通過.socket
文件來,uwsgi配置的是http協(xié)議
鬓照;或者本地開發(fā)過程中uwsgi啟動或者配置時采用socket=127.0.0.1:9999
,而瀏覽器是http請求熔酷,也會報錯,具體看實(shí)際情況豺裆。
2. 啟動出現(xiàn)!!! no internal routing support, rebuild with pcre support !!!
這個是沒有內(nèi)部路由支持拒秘,需要通過使用pcre
重新構(gòu)建。需要先停掉uwsgi項(xiàng)目臭猜,然后重構(gòu)下載依賴躺酒,具體做法為
# 卸載原有的uwsgi
pip uninstall uwsgi
# 安裝pcre
sudo apt-get install libpcre3 libpcre3-dev
# 重新下載uwsgi --no-cache-dir意思是不從緩存中用上次編譯的uwsgi文件
pip install uwsgi --no-cache-dir
3. uwsgi提示 No such file or directory [core/utils.c line 3654]
我的路徑?jīng)]有問題,而且蔑歌,可為何還是提示沒有這個文件呢羹应?檢查文件內(nèi)容是否有注釋,次屠。
注意一下幾點(diǎn),但不一定全是:
- 注意啟動的時候
--ini uwsgi_flask.ini
后面沒有空格- 檢查文件.ini內(nèi)容是否有注釋量愧,將注釋全部刪除即可
- 檢查文件.ini內(nèi)容是否有空格,將空格全部刪除
- 路徑有誤帅矗!將當(dāng)前含有uwsgi_flask.ini的目錄掛載到容器里(我的uwsgi.ini在BackServer里面)
# When I fixed it, all started work as expected. docker run -itd --name flask_env_container2 -v $PWD/BackServer:/app -p 9999:9999 flask_env:latest uwsgi --plugin=python3 --ini uwsgi.ini
4. 提示failed to build: COPY failed: stat /var/lib/docker/tmp:no such file or directory
本質(zhì)上還是路徑不對,檢查文件別寫錯了煞烫。例外注意/dirname
跟/dirname/
區(qū)別
dockerfile沒有指定上下文(就是你運(yùn)行的dockerfile所在目錄就是主路徑浑此,后面復(fù)制文件等操作以此相對應(yīng))
docker-compose文件已經(jīng)指定了上下文,后面你又執(zhí)行了某個路徑下的dockerfile滞详,那么對于當(dāng)前service而言凛俱,你的dockerfile的上下文不再是dockerfile所在目錄,而是你compose所指定的路徑(context:)
就是copy 或者add 后面的路徑?jīng)]有/ 例如
copy a /mydir
應(yīng)該改成copy a /mydir/
5. mysql提示Failed to get stat for directory pointed out by --secure-file-priv
vim /etc/my.cnf # (數(shù)據(jù)庫配置文件)
secure-file-priv="/" # (即可將數(shù)據(jù)導(dǎo)出到任意目錄)
如果是通過配置文件添加的料饥,則修改my.cnf
# 添加[mysqld]
secure_file_priv=""
6. Supplied value : /var/lib/mysql-files
/var/lib/mysql-files 文件是否存在或者權(quán)限問題
touch /var/lib/mysql-files
chown -R 777 /var/lib/mysql-files
五蒲犬、項(xiàng)目展示和項(xiàng)目地址
1. docker-compose編排成功后的截圖
flask成功創(chuàng)建界面:2. 項(xiàng)目界面
基于python flask和前端Vue.js、Element-ui等前后端分離的后臺用戶管理,整合爬蟲項(xiàng)目岸啡。提供了CSRF防護(hù)原叮,權(quán)限驗(yàn)證,數(shù)據(jù)庫備份導(dǎo)出excel,日志記錄奋隶,定時任務(wù)擂送,郵箱發(fā)送等功能,詳見Github
一兩個月的努力唯欣,希望大家能夠支持嘹吨,謝謝。期待您的start~
3.寫在最后
由于時間關(guān)系境氢,開發(fā)文檔沒有來的及編寫蟀拷,但代碼注釋說明寫的很詳細(xì),項(xiàng)目可分成三部分使用本地開發(fā)萍聊、線上部署问芬、和docker環(huán)境 (對于爬蟲那塊需要自行部署selenium和chromium)部署。歡迎大家相互學(xué)習(xí)交流脐区,評論區(qū)留言交流愈诚。