docker前后端分離部署(flask+vue)和編排

文章目錄
[一、docker安裝MySql和Redis并啟動]
- [1. docker安裝]
- [2.docker啟動安裝的鏡像]
- [3. 查看docker啟動鏡像的時候所用的命令]
- [4. 停止和刪除鏡像容器]
- [5. 登陸和修改、提交鏡像]
[二、每個鏡像都有資源彼此獨立]
- [1. 如何查看docker里面container的ip]
- [2. docker創建的容器具有ip的原因和通信方式]
- [3. docker-compose編排容器并啟動]
- [4. 需要注意mysql和redis的ip修改]
[三、分離部署docker+nginx+uwsgi+mysql+redis]
- [1. 設計圖和項目路徑]
- [2. Dockerfile編寫]
[四、uwsgi和docker爬坑]
- [1. 報錯invalid request block size: zxx...skip]
- [2. 啟動出現!!! 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]
[五、項目展示和項目地址]
[1. docker-compose編排成功后的截圖]
[2. 項目界面的截圖]
[3.寫在最后]

今天給大家帶來前后端分離項目下的docker的部署和啟動,到最終的打包提交到dockerhub,以及爬坑記錄。旨在解決同道小伙伴們的痛點。
?剛學習docker,不足之處望請諒解,虛心接受大神指點,轉注出,誠謝~ 文末附項目效果展示和源碼地址。

一、docker安裝MySql和Redis并啟動

官網命令傳送門==>docker命令

1. docker安裝

  • 查詢有哪些鏡像
$ docker search mysql
  • 安裝指定的鏡像(在此之前請先配制好鏡像加速)
$ docker pull mysql:8.0.18
  • 安裝默認最新鏡像
$ 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鏡像以守護進程的方式創建實例mysql-demo(容器)
# 該實例的端口為3306對應的宿主機上的12345,初始化的數據庫密碼為5201020116.
# 也可以將宿主機的數據庫的配置掛載到mysql-demo對應的位置
$ docker run -p 12345:3306 --name mysql-demo -e MYSQL_ROOT_PASSWORD=5201020116 -d mysql

因為我的mysql的宿主機環境已經安裝了,所以宿主機端口不能在用3306,改為了12345。

  • 啟動Redis
# 默認redis容器里是沒有配置文件的(可在容器的/etc/查看redis.conf不存在),因而需要在創建容器時映射進來
# 設置密碼直接使用--requirepass "你的密碼"即可
# -i表示以交互模式運行容器,-t表示重新分配偽終端, -d以守護進程方式運行; -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"
# 查看剛創建的容器的信息(截取部分)
$ 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
# 再次進入這個容器
$ docker exec -it a83ef0e487e7 /bin/bash
# 驗證是否成功
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
# 停止/重啟/刪除容器 (已運行需要先停止再刪除)
$ docker container stop/restart/rm  a83ef0e487e7#容器ID
# 直接強制刪除
$ docker rm -f a83e#容器ID
# #刪除鏡像image,刪除前需要保證沒有container引用這個鏡像
$ docker rmi 9b51d9275906   #鏡像id
# 刪除所有鏡像
$ docker rmi $(docker images -q)
# 刪除所有沒有標簽的鏡像
$ 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
# 提交到遠程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

二、每個鏡像都有資源,彼此獨立

1. 如何查看docker里面container的ip

$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 053e4f11df7a

因而想要讓docker內部容器間訪問就需要通過ip來實現。例如后端python項目和mysql交互。

2. docker創建的容器具有ip的原因

  • ?宿主機在安裝docker后,docker會在宿主機上生成一張docker虛擬網卡,docker網卡通過NAT的方式為每一個容器分配ip,容器同處于docker網段下,因而容器間通信,可以通過ip。
  • 而容器和宿主機器通信,則是通過docker虛擬網卡進行轉發路由。
  • 鏡像創建了容器后,容器名會對應容器ip(在該容器的host有映射),因而可以通過容器名執行相關操作.

如下示意圖 :
container-ip.png

三、前后端分離部署(docker+nginx+uwsgi+mysql+redis)

1. 設計圖和項目路徑

docker 的設計示意圖.(其中nginx的反向代理協議用的是wsgi,添加了include uwsgi_params;,用了uwsgi_pass因為后臺服務器用uwsgi;正常情況使用proxy_pass即可)

docker-Architecture.png

項目文件 簡易說明

  • BackServer/ ----后端源碼項 目
  • vue_admin/ ---- 前端項目
  • dist/ ---- 打包后線上部署的文件
  • docker/ ---- mysql、redis、nginx的配置和dockerfile
  • Dockerfile ---- BackServer托管uwsgi服務器的dockerfile

項目文件說明圖:
project_trees.png

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
    # 把主機的nginx.conf文件復制到nginx容器的/etc/nginx文件夾下
    ADD ./docker/web/nginx.conf /etc/nginx/
    # 容器間暴露8080端口.如果是云服務器部署,記得在安全組添加開放端口8080。
    # 也可以在docker run -p指定具體的,或者-P默認expose暴露的端口
    EXPOSE 8080
    # CMD命令用于容器啟動時執行,而不像RUN的鏡像構建時候運行
    # 使用daemon off的方式將nginx運行在前臺保證鏡像不退出
    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的初始化數據庫和表的腳本
    #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編寫啟動的順序(依賴關系)要注意 參考redis -> mysql -> uwsgi -> nginx。例外,一旦指定了compose的某個service的上下文(主路徑),那么dockerfile的路徑將以compose設定為準,而不是dockerfile所在目錄。

version: "3.7"
services:
    redis:
        hostname:   spider-redis
        # 根據BackServer/Config/config.py配置
        container_name: spider-redis    # 不指定則會系統自動分配名稱
        restart: always  # always表容器運行發生錯誤時一直重啟
        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  # 設置容器時區與宿主機保持一致
            #- ./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:
            # 這個根據項目BackServer的Config/config.py里面的設置對應
            - MYSQL_ROOT_PASSWORD=5201020116    # 配置數據庫的密碼
        volumes:
           # 初始化數據庫信息- ./docker/mysql/Mysql_Init_Script.sql:/docker-entrypoint-initdb.d/  
            - ./docker/mysql/my.cnf:/etc/mysql/my.cnf    # 掛載配置文件-
            - /etc/localtime:/etc/localtime:ro  # 設置容器時區與宿主機保持一致
        ports:
            - "3306:3306"

    flask:
        hostname:   spider-flask
        container_name: spider-flask
        restart:    always
        build:  .   # 執行當前的目錄下的dockerfile
            # context:    ./
            # dockerfile: ./docker/uwsgi_flask/Dockerfile
        volumes:
            - /etc/localtime:/etc/localtime:ro  # 設置容器時區與宿主機保持一致
        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"   # 根據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

這個是比較常見的,問題出在請求的時候協議和對應uwsgi配置或啟動不一致,例如docker里面通過nginx容器訪問uwsgi需要通過.socket文件來,uwsgi配置的是http協議;或者本地開發過程中uwsgi啟動或者配置時采用socket=127.0.0.1:9999,而瀏覽器是http請求,也會報錯,具體看實際情況。

2. 啟動出現!!! no internal routing support, rebuild with pcre support !!!

這個是沒有內部路由支持,需要通過使用pcre重新構建。需要先停掉uwsgi項目,然后重構下載依賴,具體做法為

# 卸載原有的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]

我的路徑沒有問題,而且,可為何還是提示沒有這個文件呢?檢查文件內容是否有注釋,。

注意一下幾點,但不一定全是:

  • 注意啟動的時候 --ini uwsgi_flask.ini 后面沒有空格
  • 檢查文件.ini內容是否有注釋,將注釋全部刪除即可
  • 檢查文件.ini內容是否有空格,將空格全部刪除
  • 路徑有誤!將當前含有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

本質上還是路徑不對,檢查文件別寫錯了。例外注意/dirname/dirname/區別

  • dockerfile沒有指定上下文(就是你運行的dockerfile所在目錄就是主路徑,后面復制文件等操作以此相對應)

  • docker-compose文件已經指定了上下文,后面你又執行了某個路徑下的dockerfile,那么對于當前service而言,你的dockerfile的上下文不再是dockerfile所在目錄,而是你compose所指定的路徑(context:)

  • 就是copy 或者add 后面的路徑沒有/ 例如 copy a /mydir 應該改成 copy a /mydir/

5. mysql提示Failed to get stat for directory pointed out by --secure-file-priv

vim /etc/my.cnf     # (數據庫配置文件)
secure-file-priv="/"    # (即可將數據導出到任意目錄)

如果是通過配置文件添加的,則修改my.cnf

# 添加[mysqld]
secure_file_priv=""

6. Supplied value : /var/lib/mysql-files

/var/lib/mysql-files 文件是否存在或者權限問題

touch /var/lib/mysql-files
chown -R 777 /var/lib/mysql-files

五、項目展示和項目地址

1. docker-compose編排成功后的截圖

flask成功創建界面:
flask_docker啟動成功界面.png

redis和mysql創建頁面:
mysql初始化成功圖片.png
redis初始化成功.png

2. 項目界面

基于python flask和前端Vue.js、Element-ui等前后端分離的后臺用戶管理,整合爬蟲項目。提供了CSRF防護,權限驗證,數據庫備份導出excel,日志記錄,定時任務,郵箱發送等功能,詳見Github
一兩個月的努力,希望大家能夠支持,謝謝。期待您的start~

登陸界面:
登錄界面.png

注冊界面:
注冊界面.png

爬取和下載界面:
dashboard.png

用戶權限管理界面:
user_permission.png

日志備份下載和清空界面:
logging_backup.png

3.寫在最后

由于時間關系,開發文檔沒有來的及編寫,但代碼注釋說明寫的很詳細,項目可分成三部分使用本地開發、線上部署、和docker環境 (對于爬蟲那塊需要自行部署selenium和chromium)部署。歡迎大家相互學習交流,評論區留言交流。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373