django项目部署

# 部署

![服务器架构](../images/服务器架构图.png)

## 1. 静态文件

当Django运行在生产模式时,将不再提供静态文件的支持,需要将静态文件交给静态文件服务器。

我们先收集所有静态文件。项目中的静态文件除了我们使用的front_end_pc中之外,django本身还有自己的静态文件,如果rest_framework、xadmin、admin、ckeditor等。我们需要收集这些静态文件,集中一起放到静态文件服务器中。

**我们要将收集的静态文件放到front_end_pc目录下的static目录中,所以先创建目录static。**

Django提供了收集静态文件的方法。先在配置文件中配置收集之后存放的目录

```python

STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'front_end_pc/static')

```

然后执行收集命令收集完后注释掉防止重复跑

```shell

python manage.py collectstatic

```

我们使用Nginx服务器作为静态文件服务器

## 2.Nginx服务器安装:

在root用户下安装;sudo su进入超级用户

如果本机安装了nginx,卸载nginx

apt-get --purge autoremove nginx

检查本机是否还有nginx程序在后台运行ps -ef | grep  nginx

如果有直接kill掉 kill -9 端口号

默认版本安装

方便简单,很多依赖都自动给安装好了,一个命令即可 在root 用户下

apt-get update    # 更新包

如果在更新的时候下面没有公钥的的报错:

# 由于没有公钥,无法验证下列签名: NO_PUBKEY 9165938D90FDDD2E

则运行 下面的命令

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys  + NO_PUBKEY后面的公钥

比如:

#sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E

最后重新 apt-get update

# 安装Nginx

apt-get install nginx

```

文件介绍

```

/usr/sbin/nginx:主程序,启动文件

/etc/nginx:存放配置文件

/var/www/html:存放项目目录

/var/log/nginx:存放日志  

一般自动安装配置文件目录和主程序目录不变,因为版本原因,其它目录可能会变,但是都可以从配置文件里ngxin.conf里找到对应的位置。


 

在浏览器(Ubuntu里面的)里面访问127.0.0.1:80  显示Nginx安装成功就可以了

```



 

打开Nginx的配置文件

```shell

进入root用户:

sudo su

pythonvip

sudo vim /etc/nginx/nginx.conf

```

在server部分中配置(这里可暂时不去写,最后下面有完整的参照)

```python

# 前端服务器配置

server {

         listen       8000; # 服务的端口号

         server_name  127.0.0.1;  # 服务的id

        location / {

             root   /home/python/Desktop/front_end_pc;  # 前端服务路径

             index  index.html index.htm;

         }

        # 余下省略

}

```

> 首次启动nginx服务器

> sudo /usr/local/nginx/sbin/nginx

重启Nginx服务器

sudo /usr/sbin/nginx -s reload   重启Nginx

> 停止nginx服务器

> sudo /usr/local/nginx/sbin/nginx -s stop

查看Nginx的状态  nginx -t

### 2. 动态接口

在项目中复制开发配置文件dev.py 到生产配置prod.py

修改配置文件prod.py中

DEBUG = False

ALLOWED_HOSTS = [...,  'http://127.0.0.1:8000','http://127.0.0.1:8001']  # 添加

CORS_ORIGIN_WHITELIST = (

    .....

    #添加

    'http://127.0.0.1:8000',

    'http://127.0.0.1:8001',

    'http://127.0.0.1:8002',

)

修改wsgi.py文件

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meiduo_mall.settings.prod")

django的程序通常使用uwsgi服务器来运行

### 3安装uwsgi

在当前项目的虚拟环境中安装:

pip install uwsgi

在项目目录/好课_mall 下创建uwsgi配置文件 uwsgi.ini  该文件与manage.py同级目录

```ini

[uwsgi]

#使用nginx连接时使用,Django程序所在服务器地址

socket=192.168.1.107:8002    # 该 ip可以是服务器的地址 这里我们用Ubuntu的地址和ip

#直接做web服务器使用,Django程序所在服务器地址

#http=10.211.55.2:8001     # 这里是用做uwsgi与Django通信是否注册的时候使用的,一般在Nginx访问后端后端的接口报错的时候可以使用,一般很少用

#项目目录

chdir=/home/pyvip/hualong/haoke_mall

#项目中wsgi.py文件的目录,相对于项目目录

wsgi-file=haoke_mall/wsgi.py

# 进程数

processes=4

# 线程数

threads=2

# uwsgi服务器的角色

master=True

# 存放进程编号的文件

pidfile=uwsgi.pid

# 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的

# 方便查看报错信息的

daemonize=uwsgi.log

# 指定依赖的虚拟环境

virtualenv=/home/pyvip/.virtualenvs/hualong

# 最大运行内存

buffer-size = 65536

```

启动uwsgi服务器:在 uwsgi.ini 目录下

```shell

uwsgi --ini uwsgi.ini

```

> 注意如果想要停止服务器,除了可以使用kill命令之外,还可以通过

>

> ```shell

> uwsgi --stop uwsgi.pid

> ```

注意:

```

uwsgi --ini uwsgi.ini  启动后会生成 uwsgi.log  这个里面一定要记得去看看 ,启动是否成功,端口号是否被占用等情况  比如: 192.168.1.107:8002  已存在 则是8002被占用了

可以用命令杀掉这个端口在重启:

比如:  记得执行2次

sudo fuser -k 8002/tcp

```





 

修改Nginx配置文件,让Nginx接收到请求后转发给uwsgi服务器

```python

user root;

worker_processes auto;

pid /run/nginx.pid;

include /etc/nginx/modules-enabled/*.conf;

http {

        # 使css文件正常加载

        include       mime.types;

        default_type  application/octet-stream;

        upstream haoke111 {

                 server 192.168.1.101:8002;

     }

    # 后端的ip配置

     server {

         listen  8001;

         server_name 127.0.0.1;

         charset utf-8;


 

         location / {

             include uwsgi_params ;

             uwsgi_pass haoke111;

         }

        location /static {

               alias /home/pyvip/hualong/front_end_pc/static;

        }

     }

     # 前端的服务配置

     server {

         listen       8000;

         server_name  127.0.0.1;

         #charset koi8-r;

         #access_log  logs/host.access.log  main;

         location /admin {

             include uwsgi_params;

             uwsgi_pass haoke111;

         }

         location /ckeditor {

             include uwsgi_params;

             uwsgi_pass haoke111;

         }

         location / {

             root   /home/pyvip/hualong/front_end_pc;

             index  index.html index.htm;

         }

        # 使css文件正常加载

        location ~.*(js|css|png|gif|jpg|mp3|ogg)$ {

                        root /home/pyvip/hualong/front_end_pc/;

                }


 

         error_page   500 502 503 504  /50x.html;

         location = /50x.html {

             root   html;

         }

        }

}

events {

            worker_connections  1024;    #nginx的最大并发访问量

            use epoll;    #异步IO

        }

```

重启nginx

```shell

sudo /usr/sbin/nginx -s reload   重启Nginx

如果出现 :nginx: [error] open() “/run/nginx.pid” failed (2: No such file or directory)

则执行:

sudo nginx -c /etc/nginx/nginx.conf

然后再重启

sudo /usr/sbin/nginx -s reload

```



 

prod.py

```

"""

Django settings for haoke_mall project.

Generated by 'django-admin startproject' using Django 3.1.10.

For more information on this file, see

https://docs.djangoproject.com/en/3.1/topics/settings/

For the full list of settings and their values, see

https://docs.djangoproject.com/en/3.1/ref/settings/

"""

import datetime

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.

BASE_DIR = Path(__file__).resolve().parent.parent

# 添加导包路径

import sys

import os

sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))


 

STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'front_end_pc/static')

# Quick-start development settings - unsuitable for production

# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# 由于没有公钥,无法验证下列签名: NO_PUBKEY 9165938D90FDDD2E

# sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E

# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = '8l7jsblq%pndqi1tzh*lc#k6mq=w8xqriv5q2ivxqr2aqdap4c'


 

"""

/usr/sbin/nginx:主程序,启动文件

/etc/nginx:存放配置文件

/var/www/html:存放项目目录

/var/log/nginx:存放日志  

sudo /usr/sbin/nginx   启动Nginx

sudo /usr/sbin/nginx  -s stop  停止


 

"""


 

# SECURITY WARNING: don't run with debug turned on in production!

DEBUG = False

ALLOWED_HOSTS = ['*','http://127.0.0.1:8002','http://127.0.0.1:8001','http://127.0.0.1:8000','http://127.0.0.1:80','http://192.168.1.101:8000','http://192.168.1.101:8001']


 

# Application definition

INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'rest_framework',

    'users',

    'verifications',

    'corsheaders',

    #

    'areas',

    'goods',

    'contents',

    # 注册富文本编辑器

    'ckeditor',  # 富文本编辑器

    'ckeditor_uploader',  # 富文本编辑器上传图片模块

    'django_crontab', # 定时任务

    'haystack',

    'carts',

    'orders',

    'payment',

]

# 支付宝配置

ALIPAY_APPID = "2016101300672735"

ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"

ALIPAY_DEBUG = True

# 账号: yuhiao9778@sandbox.com

# 密码:111111

# Haystack

HAYSTACK_CONNECTIONS = {

    'default': {

        'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',

        'URL': 'http://192.168.1.101:9200/',  # 此处为elasticsearch运行的服务器ip地址,端口号固定为9200

        'INDEX_NAME': 'haoke',  # 指定elasticsearch建立的索引库的名称

    },

}

# 当添加、修改、删除数据时,自动生成索引

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

# 定时任务

CRONJOBS = [

    # 每5分钟执行一次生成主页静态文件

    ('*/1 * * * *', 'contents.crons.generate_static_index_html', '>> /home/pyvip/hualong/haoke_mall/log/crontab.log')

]

# 解决crontab中文问题

CRONTAB_COMMAND_PREFIX = 'LANG_ALL=zh_cn.UTF-8'

# 富文本编辑器ckeditor配置

CKEDITOR_CONFIGS = {

    'default': {

        'toolbar': 'full',  # 工具条功能

        'height': 300,  # 编辑器高度

        # 'width': 300,  # 编辑器宽

    },

}

CKEDITOR_UPLOAD_PATH = ''  # 上传图片保存路径,使用了FastDFS,所以此处设为''

MIDDLEWARE = [

    'corsheaders.middleware.CorsMiddleware',

    'django.middleware.security.SecurityMiddleware',

    'django.contrib.sessions.middleware.SessionMiddleware',

    'django.middleware.common.CommonMiddleware',

    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',

    'django.contrib.messages.middleware.MessageMiddleware',

    'django.middleware.clickjacking.XFrameOptionsMiddleware',

]

# CORS

CORS_ORIGIN_WHITELIST = (

    'http://192.168.110.215:8002',

    'http://127.0.0.1:8080',

    'http://127.0.0.1:8081',

    'http://127.0.0.1:8000',

    'http://127.0.0.1:8001',

    'http://127.0.0.1:8002',

    'http://127.0.0.1:80',

    'http://0.0.0.0:9000',

    'http://0.0.0.0:8000',

    'http://0.0.0.0:8001',

    'http://0.0.0.0:8002',

    # 'localhost',

    'http://192.168.222.1:8080',

    'http://192.168.1.101:8002',

    'http://192.168.1.101:8001',

    'http://192.168.1.101:8000',

    'http://api.meiduo.site',

)

CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie

# HWFZCXBBLTRBVYOG

# 以下是邮件配置

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST = 'smtp.163.com'

EMAIL_PORT = 25

#发送邮件的邮箱

EMAIL_HOST_USER = 'yike120@163.com'

#在邮箱中设置的客户端授权密码

EMAIL_HOST_PASSWORD = 'DZWFXIWBGFSYSDHZ'

#收件人看到的发件人

EMAIL_FROM = '好课商城<yike120@163.com>'


 

REST_FRAMEWORK = {

    'DEFAULT_AUTHENTICATION_CLASSES': (

        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',

        'rest_framework.authentication.SessionAuthentication',

        'rest_framework.authentication.BasicAuthentication',

    ),

    # 异常处理

    'EXCEPTION_HANDLER': 'haoke_mall.utils.exceptions.exception_handler',

    # 分页

    'DEFAULT_PAGINATION_CLASS': 'haoke_mall.utils.pagination.StandardResultsSetPagination',

}

JWT_AUTH = {

    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),

    'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',

}

AUTHENTICATION_BACKENDS = [

    'users.utils.UsernameMobileAuthBackend',

]


 

ROOT_URLCONF = 'haoke_mall.urls'

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR,'templates')],

        'APP_DIRS': True,

        'OPTIONS': {

            'context_processors': [

                'django.template.context_processors.debug',

                'django.template.context_processors.request',

                'django.contrib.auth.context_processors.auth',

                'django.contrib.messages.context_processors.messages',

            ],

        },

    },

]

WSGI_APPLICATION = 'haoke_mall.wsgi.application'

AUTH_USER_MODEL = 'users.User'

# Database

# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.mysql',

        'HOST': '127.0.0.1',  # 数据库主机

        'PORT': 3306,  # 数据库端口

        'USER': 'root',  # 数据库用户名

        'PASSWORD': 'qwe123',  # 数据库用户密码

        'NAME': 'hualong'  # 数据库名字

    }

}

CACHES = {

    "verify_codes": {   # 存储验证码

            "BACKEND": "django_redis.cache.RedisCache",

            "LOCATION": "redis://127.0.0.1:6379/2",

            "OPTIONS": {

                "CLIENT_CLASS": "django_redis.client.DefaultClient",

            }

    },

    "default": {

        "BACKEND": "django_redis.cache.RedisCache",

        "LOCATION": "redis://127.0.0.1:6379/0",

        "OPTIONS": {

            "CLIENT_CLASS": "django_redis.client.DefaultClient",

        }

    },

    "session": {

        "BACKEND": "django_redis.cache.RedisCache",

        "LOCATION": "redis://127.0.0.1:6379/1",

        "OPTIONS": {

            "CLIENT_CLASS": "django_redis.client.DefaultClient",

        }

    },

    "history": {

        "BACKEND": "django_redis.cache.RedisCache",

        "LOCATION": "redis://127.0.0.1:6379/3",

        "OPTIONS": {

            "CLIENT_CLASS": "django_redis.client.DefaultClient",

        }

    },

    "cart": {

        "BACKEND": "django_redis.cache.RedisCache",

        "LOCATION": "redis://127.0.0.1:6379/4",

        "OPTIONS": {

            "CLIENT_CLASS": "django_redis.client.DefaultClient",

        }

    },

}

SESSION_ENGINE = "django.contrib.sessions.backends.cache"

SESSION_CACHE_ALIAS = "session"

# Password validation

# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators


 

# DRF扩展

REST_FRAMEWORK_EXTENSIONS = {

    # 缓存时间

    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,

    # 缓存存储

    'DEFAULT_USE_CACHE': 'default',

}



 

# django文件存储

DEFAULT_FILE_STORAGE = 'haoke_mall.utils.fastdfs.fdfs_storage.FastDFSStorage'

# FastDFS

FDFS_URL = 'http://192.168.1.101:8888/'

FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf')


 

# 生成的静态html文件保存目录

GENERATED_STATIC_HTML_FILES_DIR = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'front_end_pc')

AUTH_PASSWORD_VALIDATORS = [

    {

        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',

    },

    {

        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',

    },

]


 

# Internationalization

# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True



 

# Static files (CSS, JavaScript, Images)

# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'

LOGGING = {

    'version': 1,

    'disable_existing_loggers': False,  # 是否禁用已经存在的日志器

    'formatters': {  # 日志信息显示的格式

        'verbose': {

            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'

        },

        'simple': {

            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'

        },

    },

    'filters': {  # 对日志进行过滤

        'require_debug_true': {  # django在debug模式下才输出日志

            '()': 'django.utils.log.RequireDebugTrue',

        },

    },

    'handlers': {  # 日志处理方法

        'console': {  # 向终端中输出日志

            'level': 'INFO',

            'filters': ['require_debug_true'],

            'class': 'logging.StreamHandler',

            'formatter': 'simple'

        },

        'file': {  # 向文件中输出日志

            'level': 'INFO',

            'class': 'logging.handlers.RotatingFileHandler',

            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"),  # 日志文件的位置

            'maxBytes': 300 * 1024 * 1024,

            'backupCount': 10,

            'formatter': 'verbose'

        },

    },

    'loggers': {  # 日志器

        'django': {  # 定义了一个名为django的日志器

            'handlers': ['console', 'file'],  # 可以同时向终端与文件中输出日志

            'propagate': True,  # 是否继续传递日志信息

            'level': 'INFO',  # 日志器接收的最低日志级别

        },

    }

}


 

```

### 4.访问测试部署是否成功:

```

1.直接访问前端服务器的接口:127.0.0.1:8000  看看前端显示是否正常

2.访问127.0.0.1:8001 后端服务器是否正常返回数据  

3.没有问题后,访问127.0.0.1:8000  进行商品的购买操作,没有问题的话

4到此项目部署成功了

```












 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值