Docker部署Angular+Nginx+uwsgi+Django项目


0、前言


在开发部署时,容易遇到服务器环境不一致,多台服务重复部署操作过于繁杂的情况。这时可以采用Docker来提供一套统一的环境和帮助我们快速部署项目。
本篇文章先介绍下Docker是什么,怎么安装使用,然后用一个比较常见的Angular+Nginx+uwsgi+Django框架模式的项目的说明怎么用Docker将各个服务结构搭建连接使用,说了下怎么利用Docker来提供环境来生成Angular编译打包的文件。

第一章简单的介绍Docker并说明其安装方式(已了解过Docker可以忽略)。
第二章说明各个结构服务项目部署以及其配置文件。
第三章怎么使用Docker Compose对Docker进行整合运用发布。

1、Docker介绍


Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

Docker的应用场景

  1. Web 应用的自动化打包和发布。
  2. 自动化测试和持续集成、发布。
  3. 在服务型环境中部署和调整数据库或其他的后台应用。
  4. 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。

1.1、Docker 安装

命令行运行docker命令的时候,需要本机有 Docker 服务。
安装方式最好根据官方文档说明进行安装。
这里说明下Debian系统的安装流程

sudo apt-get update
sudo apt-get install \apt-transport-https \ca-certificates \curl \gnupg2 \software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

如果服务没有启动,可以用以下指令启动

sudo service docker start                         # service 命令的用法
sudo systemctl start docker                     # systemctl 命令的用法

验证是否安装成功

sudo docker run hello-world

查看到Hello from Docker 即表示安装成功

Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组。
注:输入指令后需要关闭终端重新连接生效。

sudo usermod -aG docker $USER

1.2、Docker基本概念

Docker主要有三个基本概念,仓库(Repository)、镜像(Image)、容器(Container)。

仓库:Docker仓库的概念和Git类似,仓库注册服务器可以理解为GitHub的托管服务。其区别在于Git仓库是提供代码文件的存储和下载,Docker仓库是提供镜像文件存储和下载,用户创建了镜像后可以push到仓库中,下次需要使用可以从仓库pull下来。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式,仓库的概念有时会和仓库注册服务器(Registry)混为一谈,但实际是仓库注册服务器上存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同标签(tag)。

Docker官方维护了一个公共仓库 Docker Hub ,基本的需求都可以通过Docker Hub 下载镜像实现。

用户无需登录即可通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull命令来将它下载到本地。

镜像:Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。

容器:Docker利用容器运行应用,是从镜像创建的实例。每个容器都是相互隔离。

可以通过–help 查看docker 指令,参数,作用。

2、项目部署


项目结构

Safety
├── SafetyTest                            # 从git 仓库
├── SafetyServer                        # 从git 仓库clone下来的Django 项目代码
├── docker-compose.yml           # docker-compose文件
├── docker-front.compile            # 前端Angular环境的Dockerfile文件
├── docker-server.compile         # 后端Django环境的Dockerfile文件
├── docker-nginx.complile         # 配置nginx的Dockerfile文件
├── www                                    # 存放Angular编译后的文件
├── mysql                                  # 存放mysql数据文件,MySQL数据持久化
├── nginx.conf                           # nginx 通用配置文件
├── conf.d                                  # nginx 配置路由文件夹
├── ├── safetyfront.conf          # 前端配置文件
├── ├── safetyserver.conf       # 后端配置文件

完整的服务通过Mysql服务提供数据存储,Web应用服务提供功能使用,Nginx服务做运维HTTP服务器和反向代理服务器。

2.1、 MySql服务容器服务

docker run -p 3307:3360 -d --volume "$PWD/mysql/":/var/lib/mysql --env MYSQL_ROOT_PASSWORD=123456 --env MYSQL_DATABASE=safety --name=safety_mysql mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

运行该命令会通过mysql:5.7镜像(本地无该镜像则会自动从官方仓库拉取该镜像)生成mysql服务容器

  • -p 端口映射,格式为:主机(宿主)端口:容器端口;
  • d: 后台运行容器,并返回容器ID;
  • –volume 挂载,将本地文件夹挂载到容器中,格式为: 主机文件夹路径:容器文件夹路径,挂载了mysql数据目录,可实现数据持久化
  • –env 设置环境变量,这里设置了mysql root用户密码和生成名为safety 的mysql数据库,(mysql镜像设置了生成容器后的自动运行脚本,会安装mysql数据库并根据设置的环境变量做一些自动化处理);
  • –name 为容器指定一个名称;
docker ps

查看运行中的容器,若NAMES 列存在 为容器设置的别名则表示容器生成成功。

docker exec  -it safety_mysql /bin/bash
#进入容器
mysql -u root -p
#使用数据库,并输入密码
show databases
#查看数据库

若存在环境变量设置的数据库名称则表示数据库生成成功。

2.2、Web应用容器服务

由于不同web应用所需依赖环境不一致,一般情况需要编写Dockerfile文件来生成镜像,再由镜像文件生成容器。镜像上传了仓库则可直接下载仓库镜像生成容器。

在构建 Docker 容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快,而且为了保证项目代码的保密性,不建议将项目代码放入镜像文件中,所以在生成环境时只生成项目所需的运行环境到镜像中,运行时通过配置volume 将项目代码文件挂载在容器中即可。

2.2.1、编写镜像文件,uwsgi配置文件和项目启动脚本

docker-server.compile

FROM python:2.7
LABEL authors=""
WORKDIR /usr/src/app/
COPY SafetyTestServer/requirements.txt requirements.txt
RUN pip install -r requirements.txt
ENTRYPOINT ["sh","restart.sh"]
  • FROM python:2.7: 继承python:2.7镜像生成
  • LABEL: 标签,一般写说明Dockerfile文件编写者的信息
  • WORKDIR: 指定接下来的工作路径,路径不存在会创建路径
  • COPY : 将本地文件拷贝到镜像文件目录中
  • RUN : 运行指令,用与安装指令
  • ENTRYPOINT: 配置容器启动时运行的命令

运行 docker build 指令生成镜像

docker build -f docker-server.compile -t safetyserver-env .
  • -f: 指定DockerFile文件
  • -t: 指定镜像名及版本号,格式 镜像名:版本号
  • 命令行尾部的 . 表示当前目录

Safety/SafetyTestServer目录为应用代码目录,目录下存在uwsgi.ini文件及restart.sh 文件,uwsgi.ini文件为通过uwsgi启动Django项目的配置文件,restart.sh则是处理启动的脚本。
uwsgi.ini

[uwsgi]
chdir = /usr/src/app
module = SafetyTest.wsgi:application
socket = 0.0.0.0:82
master = true
pidfile = /usr/src/app/safetytest.pid
env DJANGO_SETTINGS_MODULE = SafetyTest.settings
processes = 5
harakiri = 20
max-requests = 5000
vacuum = true
buffer-size = 32768
daemonize = /usr/src/app/uwsgi.log

restart.sh

uwsgi --stop /tmp/safetytest.pid
sleep 3
uwsgi --ini uwsgi.ini
sleep infinity #为保持容器不自动关闭

2.2.2、启动容器

docker run -p 82:82 -d --rm --volume "$PWD/SafetyTestServer/":/usr/src/app/ --name=safety_server --link=safety_mysql:safety_mysql safetyserver-env

2.3、Nginx容器服务


2.3.1、Angular 编译打包

熟悉Angular 项目的同学应该知道Angular需要经过编译生成dist文件,前端实际显示的为dist文件内容。Angular是通过node进行编译的,而且需要安装对应的模块依赖。
为了保障环境的稳定,所以我将编译Angular项目的环境也Docker化,确保各个服务器的依赖的统一。

编写镜像文件docker-front.compile

docker-front.compile

FROM node:10
LABEL authors="lq"
WORKDIR /usr/src/app
COPY SafetyTest/package.json package.json
RUN npm install
RUN npm install -g @angular/cli

同样镜像文件中我并没有放入项目代码,那么如何实现将项目代码通过环境进行编译生成dist文件并获取呢?这里编写了docker-front.sh脚本处理。

docker-front.sh
#!/bin/bash
# author:a="true"
#如果运行脚本时添加true, 如:sh docker-front.sh true,则会更新镜像
if [ $1 = $a ]
thenecho 'new environment'docker build -f Dockerfile.compile -t safetytest-env:latest .
#生成新的镜像docker push safetytest-env:latestecho 'new environment success'
elseecho 'old environment'
fiecho 'pull environment'
docker pull safetytest-env
#向仓库拉取镜像
echo 'pull environment success'
docker run -itd --name safety safetytest-env /bin/bash
#运行镜像生成名为safety 的容器
docker cp ./SafetyTest/ safety:/usr/src/app/
#拷贝本地文件到safety容器中
docker exec safety ng build --prod --aot
# 对safety容器执行ng build --prod --aot 指令编译打包文件
docker cp safety:/usr/src/app/dist ./www/dist
#拷贝safety容器中编译生成好的dist文件到本地www文件夹中
docker container stop safety
#停止safety容器
docker container rm safety
#移除safety容器 (容器停止后可以通过start 重新恢复容器运行,如果不需要该容器了则stop后需要移除,释放系统资源)

运行完后查看www文件夹中是否存在dist文件,存在表示运行成功,Angular编译打包完成

2.3.2、Nginx配置文件

Nginx提供服务需要通过配置相应项目的Nginx服务启动。

Safety 文件目录下有nginx.conf通用配置文件,conf.d 项目文件夹,nginx.conf通用配置一般是为了为Nginx设置一些通用参数来提供性能,可以替换可以不替换。conf.d目录下则是具体项目的配置文件。
conf.d
├── safetyfront.conf # 前端配置文件
└── safetytest.conf # 后端配置文件

safetyfront.conf

server {listen 80;server_name 服务器地址;charset utf-8;client_max_body_size 75M;access_log /var/www/nginxAccess-angular.log;error_log /var/www/nginxError-angular.log;location / {root /var/www/dist;index index.html;try_files $uri $uri/ /index.html;}
}

safetytest.conf

upstream safetytest{server 服务器地址:82;
}server {listen 81;server_name 服务器地址;charset utf-8;client_max_body_size 1G;keepalive_timeout 600;access_log /var/www/nginxAccess.log;error_log /var/www/nginxError.log;location / {uwsgi_pass safetytest;uwsgi_read_timeout 600;include /etc/nginx/uwsgi_params;if ($request_method = 'OPTIONS') {add_header 'Access-Control-Allow-Origin' '$http_origin';add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Authorization';add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Max-Age' 1728000;add_header 'Content-Type' 'text/plain charset=UTF-8';add_header 'Content-Length' 0;return 204;}if ($request_method ~ (POST|PUTPATCH)) {add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';}if ($request_method = 'GET') {add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';}}location /resource {alias /var/www/data/;}location /static {alias /var/www/static/;}
}

2.3.3、Nginx镜像文件及容器

编写镜像文件
docker-nginx.compile

FROM nginx:1.10.2
ADD  nginx.conf      /etc/nginx/nginx.conf
ADD  conf.d/*    /etc/nginx/conf.d/

生成nginx镜像

docker build -f docker-nginx.compile -t safety-nginx .

生成nginx容器

docker run -d -p 81:81 -p 80:80 --rm --volume "$PWD/www/":/var/www/ --name=safety_nginx  safety-nginx

这样完整的一套Docker部署就完成了,可以通过浏览器进行访问。

小提示:
Django需要初始化数据库, 可以进入容器执行对应初始化命令,或者通过编写脚本让容器运行

docker exec -it safety_server /bin/bash
python manage.py makemigrations
...#其他命令,通过exit 推出容器

3、Docker Compose


Docker Compos 是docker进行整合发布应用的利器,用来定义和运行复杂应用的Docker容器应用,可以通过编写配置文件实现多个Docker容器服务的启动。

3.1、安装

不同系统可以根据官方安装指南进行安装

Debian系统安装方式

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

验证是否安装成功

docker-compose --version

显示了docker-compose的版本好即表示安装成功

3.2、 配置文件

Docker-compose 运行时若没有指定文件则会在运行指令目录下找名为docker-compose.yml文件作为配置文件进行服务启动。

docker-compose.yml

version: '2'
services:mysql:image: mysql:5.7volumes:- ./mysql/:/var/lib/mysqlports:- 3307:3306networks:- mysqlendenvironment:- MYSQL_ROOT_PASSWORD=123456- MYSQL_DATABASE=safetyweb:image:safetyserver-envports:- 82:82networks:- mysqlendvolumes:- ./SafetyTestServer/:/usr/src/app/links:- mysqlweb-nginx:image: safety-nginxports:- 81:81- 83:80volumes:- ./www/:/var/www/links:- web
networks:mysqlend:
  • verison: 记录版本信息
  • services: 需要启动的容器服务,其子节点为用户自定义的容器服务名称
  • image: 指定启动容器的镜像
  • volumes: 文件挂载
  • ports: 容器和主机映射的端口
  • environment: 启动容器的环境变量
  • links: 链接到另一个服务容器
  • networks: 加入指定网络服务

3.3、 运行

docker-compose up #启动配置的docker容器服务
docker-compose stop #关闭配置的容器服务,容器依然存在,容器内内容不会丢失
docker-compose rm #将配置的容器服务移除

Docker部署Angular+Nginx+uwsgi+Django项目相关推荐

  1. 阿里云centos7部署:nginx+uwsgi+django+vue

    基础环境 阿里云centos7 部署架构 nginx + uwsgi nginx提供静态文件服务和反向代理: uwsgi充当Web服务器: 部署过程 修改项目的配置文件,配置收集静态文件之后存放的目录 ...

  2. 基于docker部署前后端分离项目--->docker+Dockerfile+vue+nginx+uwsgi+django+socket+负载均衡

    1. 介绍 本文基于阿里云服务器,安装的ubuntu20.04系统 适用于conten7.5系列 适用于ubuntu16.04以上系列 vue已经打包完成,所以不能使用我的vue项目 2. 部署 部署 ...

  3. 阿里云运行python项目_荐个人博客开发-06:Nginx + uWSGI + Django项目部署到阿里云服务器运行...

    版本:Python-3.8.1 + Django-2.2 + 阿里云服务器 Ubuntu-16.04 在正式部署前,需要确认几点: 服务器上已经安装相应的 Python MySQL Nginx uWS ...

  4. nginx+uWSGI + django部署项目

    项目部署 nginx+uWSGI + django 1. WSGI WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器(返回静态资源的就是web服务器,Nginx)如何与Web应用程序( ...

  5. Centos 6.5部署nginx+uwsgi+django

    Centos 6.5部署nginx+uwsgi+django 一.安装python3,系统默认是python2.6 1.安装依赖软件 yum -y install sqlite-devel yum - ...

  6. django进阶04部署上线(nginx,uwsgi,supervisor)

    原创博文地址:django进阶04部署上线(nginx,uwsgi,supervisor) django自身服务ok python manage.py runserver,验证可正常访问 uwsgi安 ...

  7. nginx+uwsgi+django环境部署部署

    首科常昊技术部 Django框架部署文档: 硬件环境:阿里云ecs服务器8核心.16GB.10Mbps 环境结构:nginx+uwsgi+django 所需软件:python-3.6.1.pip3.6 ...

  8. Nginx+uWSGI+Django方法部署Django程序

    在这种方式中,我们的通常做法是,将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求.nginx把所有静态请求自己来处理(这是NGINX的强项).然后,NGINX将所有非静态请求通过u ...

  9. 如何配置nginx+uwsgi+django?(知乎上面的看着不错)

    作者:知乎用户 链接:https://www.zhihu.com/question/27295854/answer/36365005 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

最新文章

  1. ACL 2020 亮点摘要
  2. 「机器学习速成」过拟合的风险和泛化
  3. 计算机专业勤学善思感悟,勤学善思作文600字
  4. 蓝桥杯java第六届决赛第一题--分机号
  5. CATALAN数 学习
  6. Win10最常用的快捷键,效率Max提高100%(常用的应该是最全的)
  7. vscode 里 Import “numpy“ count not be resolved
  8. OGR示例:写shp,求面与面的交和差操作
  9. Java-instanceof和类型转换
  10. java接口签名(Signature)实现方案续
  11. docker host and docker container
  12. solr集成IKAnalyzer中文分词器
  13. [转]java classLoader 体系结构
  14. html超链接图标图片,HTML-标签:图片 超链接
  15. HM5080E带平衡功能、5V USB输入、8.4V/1.5A两节锂电池充电IC
  16. sketch如何在手机中预览
  17. 【转载】发一篇能激励大家拼搏的文章,文中内容属实
  18. layui表格table固定表头第一行固定显示
  19. 炒股从负债百万,到“睡后收入”上百万,我做了这件事!
  20. 用EXCEL做九九乘法表

热门文章

  1. PEiD--查看导出函数
  2. 纽巴伦 2015新款黑白骑士系列
  3. java获取域名Whois注册信息
  4. cisco router
  5. php转义前端被编译单双引号
  6. ForexClub:卡塔尔豪掷千亿举办世界杯,钱哪儿来的?
  7. invalid privatekey问题
  8. 《考试脑科学》读书笔记
  9. SMARTFORM 条形码 二维码
  10. 向量表示 运动抛物线_高考真题,向量在抛物线中的妙用,向量优势,你还愁圆锥曲线吗?...