使用docker构建部署django+mysql项目(docker-compose)

这里需要升级docker版本,因为centos7 yum源默认自带的docker版本无法使用compose,详情见: http://nanguawu.me/container/5013.html

容器部署目录结构:

[root@vm2 web_django]# tree -L 2
.
├── db
│   ├── auto.cnf
│   ├── ca-key.pem
│   ├── ca.pem
│   ├── client-cert.pem
│   ├── client-key.pem
│   ├── data01
│   ├── ib_buffer_pool
│   ├── ibdata1
│   ├── ib_logfile0
│   ├── ib_logfile1
│   ├── mysql
│   ├── performance_schema
│   ├── private_key.pem
│   ├── public_key.pem
│   ├── server-cert.pem
│   ├── server-key.pem
│   └── sys
├── docker-compose.yml
├── Dockerfile
├── manage.py
├── requirements.txt
└── website
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
6 directories, 21 files

requirements.txt文件内容:

django==1.10.8
MySQL-python

Dockfile文件内容:

FROM python:2.7
MAINTAINER Larryliang "[email protected]"
ENV PYTHONUNBUFFERD 1
RUN mkdir /code
RUN mkdir /code/db
RUN mkdir /code/website
WORKDIR /code
ADD requirements.txt /code/
RUN  pip install -r requirements.txt -i https://pypi.douban.com/simple   --trusted-host pypi.douban.com
ADD . /code/

docker-compose.yml文件内容:

version: '3'
services:
  db:
    image: mysql
    expose: 
      - "3306"
    volumes:
      - ./db:/var/lib/mysql
    environment:
      - MYSQL_DATABASE=data01
      - MYSQL_ROOT_PASSWORD=data01
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

Build项目

[root@vm2 web_django]# docker version
Client:
 Version:      17.07.0-ce
 API version:  1.31
 Go version:   go1.8.3
 Git commit:   8784753
 Built:        Tue Aug 29 17:42:01 2017
 OS/Arch:      linux/amd64
Server:
 Version:      17.07.0-ce
 API version:  1.31 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   8784753
 Built:        Tue Aug 29 17:43:23 2017
 OS/Arch:      linux/amd64
 Experimental: false
[root@vm2 web_django]# docker-compose  build
db uses an image, skipping
Building web
Step 1/10 : FROM python:2.7
 ---> 8a90a66b719a
Step 2/10 : MAINTAINER Larryliang "[email protected]"
 ---> Using cache
 ---> 580a124b98a8
Step 3/10 : ENV PYTHONUNBUFFERD 1
 ---> Using cache
 ---> 87f8ce3ca0a2
Step 4/10 : RUN mkdir /code
 ---> Using cache
 ---> 83f26201a74f
Step 5/10 : RUN mkdir /code/db
 ---> Using cache
 ---> 06c6e22dd86a
Step 6/10 : RUN mkdir /code/website
 ---> Using cache
 ---> c0abb5fd2218
Step 7/10 : WORKDIR /code
 ---> Using cache
 ---> 942e3b5a8e20
Step 8/10 : ADD requirements.txt /code/
 ---> Using cache
 ---> 0a4a0bd7b379
Step 9/10 : RUN pip install -r requirements.txt -i https://pypi.douban.com/simple   --trusted-host pypi.douban.com
 ---> Using cache
 ---> 09600fc029fd
Step 10/10 : ADD . /code/
 ---> 11773f943a61
Successfully built 11773f943a61
Successfully tagged webdjango_web:latest

创建项目和APP

[root@vm2 web_django]# docker-compose  run web django-admin.py startproject website  .
Creating network "webdjango_default" with the default driver
Pulling db (mysql:latest)...
latest: Pulling from library/mysql
ad74af05f5a2: Already exists
0639788facc8: Pull complete
de70fa77eb2b: Pull complete
724179e94999: Pull complete
50c77fb16ba6: Pull complete
d51f459239fb: Pull complete
937bbdd4305a: Pull complete
35369f9634e1: Pull complete
f6016aab25f1: Pull complete
5f1901e920da: Pull complete
fdf808213c5b: Pull complete
Digest: sha256:96edf37370df96d2a4ee1715cc5c7820a0ec6286551a927981ed50f0273d9b43
Status: Downloaded newer image for mysql:latest
Creating webdjango_db_1 ... 
Creating webdjango_db_1 ... done

修改配置website/settings.py如下,之后重新build

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'data01',
        'USER': 'root',
        'PASSWORD': 'data01',
        'HOST': 'db',
        'PORT': '3306',
    }
}

启动容器:

[root@vm2 web_django]# docker-compose  up
Starting webdjango_db_1 ... 
Starting webdjango_db_1 ... done
Recreating webdjango_web_1 ... 
Recreating webdjango_web_1 ... done
Attaching to webdjango_db_1, webdjango_web_1
db_1   | 2017-09-07T12:22:23.513202Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
db_1   | 2017-09-07T12:22:23.515941Z 0 [Note] mysqld (mysqld 5.7.19) starting as process 1 ...
db_1   | 2017-09-07T12:22:23.612191Z 0 [Note] InnoDB: PUNCH HOLE support available
db_1   | 2017-09-07T12:22:23.612240Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1   | 2017-09-07T12:22:23.612247Z 0 [Note] InnoDB: Uses event mutexes
db_1   | 2017-09-07T12:22:23.612252Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
db_1   | 2017-09-07T12:22:23.612256Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.3
db_1   | 2017-09-07T12:22:23.612260Z 0 [Note] InnoDB: Using Linux native AIO
db_1   | 2017-09-07T12:22:23.612510Z 0 [Note] InnoDB: Number of pools: 1
db_1   | 2017-09-07T12:22:23.612640Z 0 [Note] InnoDB: Using CPU crc32 instructions
db_1   | 2017-09-07T12:22:23.699132Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
db_1   | 2017-09-07T12:22:23.706780Z 0 [Note] InnoDB: Completed initialization of buffer pool
db_1   | 2017-09-07T12:22:23.708851Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db_1   | 2017-09-07T12:22:23.721021Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
db_1   | 2017-09-07T12:22:24.210121Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db_1   | 2017-09-07T12:22:24.210959Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db_1   | 2017-09-07T12:22:24.884250Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db_1   | 2017-09-07T12:22:24.937435Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
db_1   | 2017-09-07T12:22:24.937508Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
db_1   | 2017-09-07T12:22:24.938536Z 0 [Note] InnoDB: Waiting for purge to start
db_1   | 2017-09-07T12:22:24.989070Z 0 [Note] InnoDB: 5.7.19 started; log sequence number 12143700
db_1   | 2017-09-07T12:22:24.989543Z 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db_1   | 2017-09-07T12:22:24.992481Z 0 [Note] Plugin 'FEDERATED' is disabled.
db_1   | 2017-09-07T12:22:25.148161Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
db_1   | 2017-09-07T12:22:25.186490Z 0 [Warning] CA certificate ca.pem is self signed.
db_1   | 2017-09-07T12:22:25.189451Z 0 [Note] Server hostname (bind-address): '*'; port: 3306
db_1   | 2017-09-07T12:22:25.189543Z 0 [Note] IPv6 is available.
db_1   | 2017-09-07T12:22:25.189564Z 0 [Note]   - '::' resolves to '::';
db_1   | 2017-09-07T12:22:25.189595Z 0 [Note] Server socket created on IP: '::'.
db_1   | 2017-09-07T12:22:25.314065Z 0 [Note] InnoDB: Buffer pool(s) load completed at 170907 12:22:25
db_1   | 2017-09-07T12:22:25.320253Z 0 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.320383Z 0 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.320534Z 0 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.320580Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.337153Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.486920Z 0 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.486995Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
db_1   | 2017-09-07T12:22:25.741875Z 0 [Note] Event Scheduler: Loaded 0 events
db_1   | 2017-09-07T12:22:25.742708Z 0 [Note] mysqld: ready for connections.
db_1   | Version: '5.7.19'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
db_1   | 2017-09-07T12:22:25.742789Z 0 [Note] Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' to get a list of tables using the deprecated partition engine. You may use the startup option '--disable-partition-engine-check' to skip this check. 
db_1   | 2017-09-07T12:22:25.742799Z 0 [Note] Beginning of list of non-natively partitioned tables
db_1   | 2017-09-07T12:22:25.877821Z 0 [Note] End of list of non-natively partitioned tables

或者放到后台启动:

[root@vm2 web_django]# docker-compose  up -d
Starting webdjango_db_1 ... 
Starting webdjango_db_1 ... done
Starting webdjango_web_1 ... 
Starting webdjango_web_1 ... done

测试结果:

[root@vm2 web_django]# curl  http://192.168.100.120:8000/ 
<!DOCTYPE html>
<html lang="en"><head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="robots" content="NONE,NOARCHIVE"><title>Welcome to Django</title>
  <style type="text/css">
    html * { padding:0; margin:0; }
    body * { padding:10px 20px; }
    body * * { padding:0; }
    body { font:small sans-serif; }
    body>div { border-bottom:1px solid #ddd; }
    h1 { font-weight:normal; }
    h2 { margin-bottom:.8em; }
    h2 span { font-size:80%; color:#666; font-weight:normal; }
    h3 { margin:1em 0 .5em 0; }
    h4 { margin:0 0 .5em 0; font-weight: normal; }
    table { border:1px solid #ccc; border-collapse: collapse; width:100%; background:white; }
    tbody td, tbody th { vertical-align:top; padding:2px 3px; }
    thead th {
      padding:1px 6px 1px 3px; background:#fefefe; text-align:left;
      font-weight:normal; font-size:11px; border:1px solid #ddd;
    }
    tbody th { width:12em; text-align:right; color:#666; padding-right:.5em; }
    #summary { background: #e0ebff; }
    #summary h2 { font-weight: normal; color: #666; }
    #explanation { background:#eee; }
    #instructions { background:#f6f6f6; }
    #summary table { border:none; background:transparent; }
  </style>
</head>
<body>
<div id="summary">
  <h1>It worked!</h1>
  <h2>Congratulations on your first Django-powered page.</h2>
</div>
<div id="instructions">
  <p>
    Of course, you haven't actually done any work yet. Next, start your first app by running <code>python manage.py startapp [app_label]</code>.
  </p>
</div>
<div id="explanation">
  <p>
    You're seeing this message because you have <code>DEBUG = True</code> in your Django settings file and you haven't configured any URLs. Get to work!
  </p>
</div>
</body></html>

观察容器状态:

[root@vm2 web_django]# docker ps  
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
2d549e242606        webdjango_web       "python manage.py ..."   7 minutes ago       Up 50 seconds       0.0.0.0:8000->8000/tcp   webdjango_web_1
ce18133de30c        mysql               "docker-entrypoint..."   About an hour ago   Up 51 seconds       3306/tcp                 webdjango_db_1
[root@vm2 web_django]# docker top 2d549e242606  #查看容器中进程
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                20355               20335               0                   08:28               ?                   00:00:00            python manage.py runserver 0.0.0.0:8000
root                20433               20355               1                   08:28               ?                   00:00:05            /usr/local/bin/python manage.py runserver 0.0.0.0:8000
[root@vm2 web_django]# docker exec -it  2d549e242606 df -Th  #容器中执行一条命令并返回
Filesystem          Type     Size  Used Avail Use% Mounted on
overlay             overlay   27G  3.9G   24G  15% /
tmpfs               tmpfs    489M     0  489M   0% /dev
tmpfs               tmpfs    489M     0  489M   0% /sys/fs/cgroup
/dev/mapper/cl-root xfs       27G  3.9G   24G  15% /code
shm                 tmpfs     64M     0   64M   0% /dev/shm
tmpfs               tmpfs    489M     0  489M   0% /sys/firmware
[root@vm2 web_django]# docker diff  2d549e242606  #查看容器变化
C /usr
C /usr/local
C /usr/local/lib
C /usr/local/lib/python2.7
A /usr/local/lib/python2.7/decimal.pyc
A /usr/local/lib/python2.7/UserList.pyc
A /usr/local/lib/python2.7/argparse.pyc
A /usr/local/lib/python2.7/BaseHTTPServer.pyc
C /usr/local/lib/python2.7/wsgiref
A /usr/local/lib/python2.7/wsgiref/__init__.pyc
A /usr/local/lib/python2.7/wsgiref/simple_server.pyc
A /usr/local/lib/python2.7/wsgiref/util.pyc
A /usr/local/lib/python2.7/wsgiref/handlers.pyc
A /usr/local/lib/python2.7/wsgiref/headers.pyc
A /usr/local/lib/python2.7/imghdr.pyc
C /usr/local/lib/python2.7/email
C /usr/local/lib/python2.7/email/mime
A /usr/local/lib/python2.7/email/mime/nonmultipart.pyc
A /usr/local/lib/python2.7/email/mime/message.pyc
A /usr/local/lib/python2.7/email/mime/base.pyc
A /usr/local/lib/python2.7/email/mime/multipart.pyc
A /usr/local/lib/python2.7/email/mime/audio.pyc
A /usr/local/lib/python2.7/email/mime/image.pyc
A /usr/local/lib/python2.7/email/mime/text.pyc
A /usr/local/lib/python2.7/sndhdr.pyc
[root@vm2 web_django]# docker inspect 2d549e242606 
[
    {
        "Id": "2d549e2426067461adc1d635bb5f41db464bf0b8d57fbe57ddd9b5381c67e24e",
        "Created": "2017-09-07T12:22:22.395256812Z",
        "Path": "python",
        "Args": [
            "manage.py",
            "runserver",
            "0.0.0.0:8000"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 20355,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2017-09-07T12:28:57.89394279Z",
            "FinishedAt": "2017-09-07T12:28:52.523766859Z"
        },
        ...
        ...
            "Networks": {
                "webdjango_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "web",
                        "2d549e242606"
                    ],
                    "NetworkID": "fc66e543785ee4abb611ad6b3319717fb0f6af56fd710358990e0f0309d34b59",
                    "EndpointID": "54ef82cd8b8bcea0abe60e4c9428ab6401839ac1df6972be6da9b75923372994",
                    "Gateway": "172.18.0.1",
                    "IPAddress": "172.18.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:12:00:03",
                    "DriverOpts": null
                }
            }
        }
    }
]

关闭容器:

[root@vm2 web_django]# docker-compose  down 
Stopping webdjango_web_1 ... done
Stopping webdjango_db_1  ... done
Removing webdjango_web_1     ... done
Removing webdjango_web_run_5 ... done
Removing webdjango_web_run_4 ... done
Removing webdjango_web_run_3 ... done
Removing webdjango_web_run_2 ... done
Removing webdjango_web_run_1 ... done
Removing webdjango_db_1      ... done
Removing network webdjango_default

至此django环境搭建测试完毕。

ubuntu16.04使用nginx、uwsgi部署django应用

安装相关软件

更新源

sudo apt-get update 
sudo apt-get upgrade

安装虚拟环境

sudo apt-get install Python-virtualenv

安装nginx

sudo apt-get install nginx

安装uwsgi

sudo pip3 install uwsgi

或者

sudo pip3 install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz

安装uwsgi出错就安装

sudo apt-get install python-dev 
sudo apt-get install python3.5-dev

本文用到的软件环境

  • ubuntu 16.04
  • Python 3.5.2
  • Django 1.11.4
  • nginx 1.10.3
  • uwsgi 2.0.15

创建一个普通用户

创建用户组webapps

sudo groupadd –system webapps

创建用户user_test并设置密码

sudo useradd –system –gid webapps –shell /bin/bash –home /webapps/test user_test

passwd user_test

创建用户目录并修改目录权限

mkdir -p /webapps/test

chown user_test /webapps/test/

添加用户user_test sudo权限

在/etc/sudoers添加

user_test ALL=(ALL:ALL) ALL

创建测试应用

切换用户为user_test

su - user_test

cd /webapps/test

创建python虚拟环境,这里指定为3.5版本,并激活

virtualenv -p /usr/bin/python3.5 .

source bin/activate

安装django

pip install django

创建django工程mysite

django-admin startproject mysite

创建应用app

cd mysite

django-admin startapp app

修改mysite/settings.py

将外网ip添加到ALLOWED_HOSTS

ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx', '127.0.0.1']

在INSTALLED_APPS里追加 ‘app’

新建app/static目录

在mysite/settings.py里添加

STATIC_ROOT = os.path.join(BASE_DIR, 'app', 'static')

收集静态文件到app/static目录

python manage.py collectstatic

迁移数据库

python manage.py migrate

创建后台管理用户

python manage.py createsuper

添加视图函数

在app/views.py添加

from django.http import HttpResponse
def index(request):
    return HttpResponse('<h1>Hello World!</h1>')

在mysite/urls.py添加

from app import views
urlpatterns = [
    ...
    url(r'^$', views.index),
]

测试django应用运行是否正常

python manage.py runserver

使用curl命令访问

curl 127.0.0.1:8000

正常会输出 <h1>Hello World!</h1>

Ctrl C 退出

当前所涉及的一些目录

  • 用户目录:/webapps/test
  • 虚拟环境目录: /webapps/test
  • 工程目录:/webapps/test/mysite

配置ngnix

从https://github.com/nginx/nginx/blob/master/conf/uwsgi_params下载到/etc/nginx/conf/目录

新建mysite/test_ngnix.conf文件,内容如下

# the upstream component nginx needs to connect to
upstream testapp {
    server unix:///webapps/test/mysite/mysite.sock; # for a file socket
    #server 127.0.0.1:9090; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      80;
    # the domain name it will serve for
    server_name localhost; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste
    access_log      /webapps/test/mysite/nginx_access.log;
    error_log       /webapps/test/mysite/nginx_error.log;

    # Django media
    location /media  {
        alias /webapps/test/mysite/app/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /webapps/test/mysite/app/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  testapp;
        include     /etc/nginx/conf/uwsgi_params; # the uwsgi_params file you installed
    }
}

将test_ngnix.conf链接到/etc/nginx/sites-enabled/目录

sudo ln -s /webapps/test/mysite/test_ngnix.conf /etc/nginx/sites-enabled/

记得删除自带的default文件,否则输入外网ip看到的是ngnix欢迎页

sudo rm /etc/nginx/sites-enabled/default

这里用到的是unix file socket

所以把用户www-data加到webapps用户组,否则读取socket文件时会有权限问题

sudo usermod -a -G webapps www-data

重启ngnix

sudo /etc/init.d/nginx stop 
sudo /etc/init.d/nginx start

配置uwsgi

新建wsgi.ini, 内容如下

[uwsgi]
#socket = 127.0.0.1:9090
chdir=/webapps/test/mysite
module=mysite.wsgi
master = true
processes=2
threads=2
max-requests=2000
chmod-socket=664
vacuum=true
daemonize = /webapps/test/mysite/uwsgi.log
virtualenv = /webapps/test
gid=webapps
uid=user_test
socket = /webapps/test/mysite/mysite.sock

运行uwsgi

uwsgi –ini wsgi.ini

用浏览器访问外网ip,正常会显示Hello World

使用uwsgi Emperor mode

# create a directory for the vassals
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# symlink from the default config directory to your config file
sudo ln -s /webapps/test/mysite/wsgi.ini /etc/uwsgi/vassals/
# run the emperor
sudo uwsgi --emperor /etc/uwsgi/vassals --uid user_test --gid webapps

使用nginx virtualenv uWSGI配置django运行环境

升级并安装 pip

sudo apt-get update
sudo apt-get install python-pip

安装虚拟环境

sudo pip install virtualenv virtualenvwrapper

加入到环境变量中

当前用户目录下的 Env为虚拟环境存放的目录

echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc

激活配置

source ~/.bashrc

创建虚拟环境

环境名为:firstsite

在用户当前目录下创建 Django工程

cd ~
django-admin.py startproject firstsite

django 的初始化

cd ~/firstsite
./manage.py migrate
./manage.py createsuperuser

Django静态文件配置

nano firstsite/settings.py
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
./manage.py collectstatic

安装 uWSGI

sudo apt-get install python-dev
sudo pip install uwsgi

测试是否能够正常访问 django 项目

  • http 指定进程端口8080
  • home指定虚拟环境目录
  • chdir指定 项目工程所在目录
uwsgi --http :8080 --home /home/pi/Env/firstsite --chdir /home/pi/firstsite -w firstsite.wsgi

创建 uwsgi 的配置文件

sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites

uwsgi 的配置相关内容(重点)

[uwsgi]
project = firstsite
base = /home/pi

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = %(base)/%(project)/%(project).sock
chmod-socket = 666
vacuum = true

启动守护进程

vim /etc/systemd/system/uwsgi.service

[Unit]
Description=uWSGI Emperor service
After=syslog.target

[Service]
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

重载守护进程的配置信息

sudo systemctl daemon-reload

系统重启后uwsgi守护进程自动重启

sudo systemctl enable uwsgi

启动uwsgi进程

sudo systemctl start uwsgi

nginx 的安装

sudo apt-get install nginx

nginx的配置

sudo nano /etc/nginx/sites-available/firstsite
server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/pi/firstsite;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/home/pi/firstsite/firstsite.sock;
    }
}

nginx配置生效

sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled

检查配置

sudo service nginx configtest

重启nginx

sudo service nginx restart

非 debug 模式

非 debug 模式需要重启uwsgi 服务

sudo systemctl restart uwsgi

centos部署django项目的详细总结

前期准备

yum groupinstall 'Development Tools'
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel

一、pyen安装

一键安装环境:

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

国内镜像
wget http://mirrors.sohu.com/python/3.6.2/Python-3.6.2.tar.xz -P ~/.pyenv/cache/;pyenv install 3.6.2
  • 切换版本 pyenv global
  • 切换python shell版本 pyenv shell

二、MySQL 安装设置

#yum install mysql
#yum install mysql-server
#yum install mysql-devel

mysql-server 安装失败,可以使用mariadb 代替

# yum install mariadb-server mariadb 

相关的命令:

mariadb数据库的相关命令是:

systemctl start mariadb  #启动MariaDB

systemctl stop mariadb  #停止MariaDB

systemctl restart mariadb  #重启MariaDB

systemctl enable mariadb  #设置开机启动

修改root密码

  • 以root身份在终端登陆,必须

  • 输入 mysqladmin -u root -p password root
    后面的 root 是要设置的密码

  • 回车后出现 Enter password
    输入就密码,如果没有,直接回车

创建用户

//创建用户
mysql> insert into mysql.user(Host,User,Password) values("localhost","admin",password("admin"));
//刷新系统权限表
mysql>flush privileges;

这样就创建了一个名为:admin 密码为:admin 的用户。

创建数据库(在root权限下)

create database mydb;
//授权admin用户拥有mydb数据库的所有权限。
>grant all privileges on mydb.* to admin@localhost identified by 'admin';
//刷新系统权限表
mysql>flush privileges;

三、Nginx 安装配置

官网下载

  • 直接下载.tar.gz安装包,地址:https://nginx.org/en/download.html

  • 使用wget命令下载(推荐)。

wget -c https://nginx.org/download/nginx*.tar.gz *替换具体的版本

解压

依然是直接命令:

tar -zxvf nginx-1.10.1.tar.gz
cd nginx-1.10.1

配置

其实在 nginx-1.10.1 版本中你就不需要去配置相关东西,默认就可以了。当然,如果你要自己配置目录也是可以的。

  • 使用默认配置
./configure

编译安装

make
make install

查找安装路径:

whereis nginx

启动、停止nginx

cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop
./nginx -s quit
./nginx -s reload
  • ./nginx -s quit:此方式停止步骤是待nginx进程处理任务完毕进行停止。

  • ./nginx -s stop:此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查询nginx进程:

ps aux|grep nginx

重启 nginx

  • 先停止再启动(推荐):
    对 nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。如下:
./nginx -s quit
./nginx
  • 重新加载配置文件:

当 ngin x的配置文件 nginx.conf 修改后,要想让配置生效需要重启 nginx,使用-s reload不用先停止 ngin x再启动 nginx 即可将配置信息在 nginx 中生效,如下:

./nginx -s reload

开机自启动

即在rc.local增加启动代码就可以了。

vi /etc/rc.local

增加一行 /usr/local/nginx/sbin/nginx
设置执行权限:

chmod 755 rc.local

最终nginx配置文件:

server {
  listen 8080;  #启动的nginx进程监听请求的端口
  server_name localhost;  #域名
  error_log /var/log/xxx/error.log;   #nginx错误日志,可自行设置,但必须保证提前建立好该目录和文件
  location / {
    include /path/nginx/uwsgi_params;  
    uwsgi_pass 127.0.0.1:9090;  #对于动态请求,转发到本机的9090端口,也就是uwsgi监听的端口
  }
  #error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;  
  location = /50x.html {
     root /usr/share/nginx/html;
  }
  location /static/ {
    alias /var/www/xxx/static/;   #设定静态文件所在目录
  }
  location /media/ {  
    alias /var/www/xxx/media/;    #同样自行设置,要保证目录已经建好
  }
}

四、使用uwsgi提供服务

  • 安装uwsgi
sudo pip install uwsgi
  • 启动uwsgi

切换到项目目录下,会有 proj_name/wsgi.py 文件,执行一下命令:

uwsgi --http :8080 --module your_proj_name.wsgi

就可以运行你的web项目了,这时如果在浏览其中输入127.0.0.1:8080 能够成功访问,说明你的应用服务器部署成功,已经可以对外提供服务。

这种提供服务的方式可以表示为:

the web client <-> uWSGI <-> Django

多数情况下我们不会让浏览器直接与uwsgi交互,而是加入nginx作为中间设备转发或处理请求。

后面介绍只用配置文件启动,可以后台运行
配置在项目目录新建配置文件 uwsgi_config.ini,内容如下:

[uwsgi]
socket = 127.0.0.1:8080
workers = 4
chdir = /root/www/Shop_Coupon
touch-reload = /root/www/Shop_Coupon
py-auto-reload = 1
module= shop_coupon.wsgi
pidfile = /var/run/uwsgi.pid
daemonize = /var/log/uwsgi.log

然后执行命令:

uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file

更加详细的可以参考:http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html

安装Apache2 libapache2-mod-wsgi部署Django应用

首先安装apache:

sudo apt-get update
sudo apt-get install apache2

安装完成后,启动apache:

sudo service apache2 start

然后新建Django项目的配置文件:

cd /etc/apache2/sites-available
vim 001-project.conf

这里需要注意,现在的apache服务器的配置文件的后缀是.conf,不能写成.config,否则apache会找不到对应的配置文件。

然后是编写对应的配置文件,这里贴上一个例子,对照着写就可以了:

<VirtualHost *:80>
ServerName 127.0.0.1   # 如果有域名,这里就填写对应的域名。127.0.0.1对应的是本地

RewriteEngine On
RewriteRule ^/(d-media|media|examples|screenshots)($|(/(.*))) /app/project/$0 [L]

DocumentRoot /app/project/

Alias /static/ /app/project/static/  # 如果有静态文件,则需要填写这句

<Directory /app/project>
Order Allow,Deny   
allow From All  # 这里允许所有人访问,也可以设置成有条件的访问,例如只能允许某些IP访问等等,具体设置这里不多说了
Options Indexes FollowSymLinks
</Directory>

WSGIProcessGroup project
WSGIApplicationGroup %{GLOBAL}

WSGIDaemonProcess lawyer_site python-path=/app/project:/app/ENV/project/lib/python2.7/site-packages user=ubuntu  group=ubuntu inactivity-timeout=3600
WSGIScriptAlias / /app/project/project/wsgi.py
# python-path是对应的环境,我这里使用了虚拟环境virtualenv。如果不是虚拟环境,则找到对应的路径即可。

CustomLog /app/project/logs/access.log combined
ErrorLog /app/project/logs/error.log
</VirtualHost>

编辑完apache的配置文件之后,需要在sites-enabled文件夹中设置软连接:

cd ../sites-enabled/
sudo ln -s ../sites-available/001-project.conf

同时,需要在项目目录中新建一个日志文件夹,里面存放的是Django项目运行在apache服务器上的日志:

mkdir /app/project/logs

到这里,整个部署就算是完成了,我们重启apache服务器:

sudo service apache2 restart

查看apache服务器的运行状态:

sudo service apache2 status

下面是我在配置apache的时候遇到的一些问题:

1、遇到Invalid command ‘RewriteEngine’:

sudo a2enmod rewrite
sudo service apache2 restart

2、遇到Invalid command ‘WSGIProcessGroup’:

sudo a2enmod wsgi

3、如果显示ERROR: Module mod-wsgi does not exist!:

sudo apt-get install libapache2-mod-wsgi
sudo a2enmod wsgi
sudo service apache2 restart

使用Django commands构建命令行做定时(crontab)任务

需求: 我想调用django里models.py或者views.py的函数对数据库做些增删改查的操作,可以加入crontab做管理,找了半天才发现可以用django commands来搞,就简单记录下来怎么用。

这个app的内容如下:

tree weblog/
weblog/
├── __init__.py
├── __init__.pyc
├── admin.py
├── admin.pyc
├── apps.py
├── management
│   ├── __init__.py
│   ├── __init__.pyc
│   └── commands
│       ├── __init__.py
│       ├── __init__.pyc
│       ├── delete_author.py
│       └── delete_author.pyc
├── migrations
│   ├── 0001_initial.py
│   ├── 0001_initial.pyc
│   ├── __init__.py
│   └── __init__.pyc
├── models.py
├── models.pyc
├── tests.py
└── views.py

3 directories, 19 files

简单写一个函数,功能是删除weblog_author表的一条记录:

cat weblog/management/commands/delete_author.py
from django.core.management.base import BaseCommand, CommandError
from weblog.models import Author

class Command(BaseCommand):
    help = 'delete author'

    def add_arguments(self, parser):
        parser.add_argument('author_id', nargs='+', type=int)

    def handle(self, *args, **options):
        for author_id in options['author_id']:
            try:
                author = Author.objects.get(pk=author_id)
            except Author.DoesNotExist:
                raise CommandError('Author "%s" does not exist' % author_id)

            author.delete()

            self.stdout.write(self.style.SUCCESS('Successfully delete author "%s"' % author_id))

执行

python manage.py delete_author  2
Successfully delete author “2"

加入到crontab里:

*/15 * * * * python /var/www/poll_mysite/manage.py delete_author  2 >/dev/null 2>&1

搭建nginx gunicorn mysql环境部署django应用

说实在的第一次用服务器来部署django确实有点不知所措,上网查了一些资料,准备部署一个nginx+gunicorn+django+mysql的一个博客系统。

用户环境

  • 服务器:阿里云服务器ECS
  • 镜像系统:ubuntu16.04 64位
  • 准备建立:nginx+gunicorn+django+mysql的博客系统

首先登陆到云服务器,也不知道先干什么,那么先更新一下吧

sudo apt-get update
sudo apt-get upgrade

中间可能会询问一些问题,输入y即可。

nginx

简单介绍一下,nginx是一个轻量级的高性能的web服务器,反向代理服务器以及邮件服务器。首先来配置一下nginx

sudo apt-get install nginx

一阵等待之后nginx就安装好了,首先来看一下nginx.conf配置

# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

这一段代码是安装nginx后的nginx的默认配置,关于nginx的配置优化后续再讲,现在重要的是将服务器给搭建起来,首先简单的讲解一下

在默认配置中,nginx总共分为四个部分:

1、全局设置,主要用来设置nginx的相关配置,比如设定nginx运行的用户和用户组、运行的进程数、运行的文件等。该部分设置在{}之外。

2、events设置,从字面理解,events就是事件的意思,这里是设置事件的相关配置,如事件处理方式是epoll还是select、单个进程的最大连接数,网络IO模型等。

3、http设置,这里是http服务器的相关配置,从默认配置看,大致有五种,基本配置、SSL配置、Log配置、Gzip配置以及虚拟端口设置。这里我们先看虚拟端口这只,这里用include引入了两个文件,/etc/nginx/conf.d/.conf 和/etc/nginx/site-enabled/。我这里就直接将我自己的服务器配置放在conf.d/blog.conf文件中。

server {
    listen 80;
    server_name final-skynet.xin;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real_IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

这段代码的意思是nginx监听80端口,服务器的地址是final-skynet.xin,location是一个匹配规则,匹配到监听的url,具体的匹配规则这里就不详细赘述了。匹配成功后,转发到本地的http://127.0.0.1:8080地址,这是gunicorn监听的地址,然后设置其他需要转发的内容。

4、最后一个是mail设置,由于本项目现在还用不着,所以就将默认的代码注释删除了。nginx的基本配置就到这里了。

安装gunicorn和django

sudo pip install gunicorn
sudo apt-get install django

输入上述命令就可以安装好django和gunicorn了,这里先简单的配置一下django,创建一个简单的blog应用。

1、创建新项目

django-admin startproject SkyNet

在根目录输入该命令就可以创建一个新的django项目SkyNet,然后创建一个新的blog应用

进入SkyNet文件夹可以看到该文件夹的目录结构如下

/SkyNet
    manage.py
    /SkyNet
        __init__.py
        settings.py
        urls.py
        wsgi.py

然后在SkyNet目录下运行以下命令

python manage.py startapp blog

然后可以看见SkyNet目录下多了一个blog的文件夹,这个就是新创建的blog app

2、创建index页面

那先创建一个index页面来验证一下我们的配置。

  • 在urls.py中进行配置
from django.conf.urls import url
from django.contrib import admin
from blog.views import *

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$',index,name='index')
]
  • 创建index视图
from __future__ import unicode_literals

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello , this is my first index')

现在需要在INSTALL_APPS配置创建的app和gunicorn

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'gunicorn',
    'blog',
]

下面需要通过gunicorn来启动django

gunicorn Skynet.wsgi:application -b 127.0.0.1:8080

最后在浏览器中输入网址进行验证

未分类

可能你需要重启一下你的nginx
讲到这个地方,云服务的环境部署应该是告一段落了

但是呢,在文章的开头,需要建立的是nginx+gunicorn+django+mysql的一个服务器,剩下的就是mysql的安装了

sudo apt-get install mysql-server

然后在安装的过程中提示需要设置密码,这个时候你可以选择设置密码,或者直接选择OK跳过。

我在这里是选择的跳过,安装完毕验证一下数据是否安装成功。由于我这里没有设置密码,故直接输入mysql就进入了mysql的命令行,设置密码的可以输入

mysql -u root -p

然后输入密码进入命令行。

在mysql创建数据库的时候经常出现编码问题,这里我先解决一下mysql的编码问题,在/etc/mysql/my.cnf中引用了conf.d中的文件,所以直接在/etc/mysql/conf.d/mysql.cnf进行修改。
首先查看一下mysql的编码,进入mysql命令行

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
//或者
mysql> status
--------------
mysql  Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using  EditLine wrapper

Connection id:      4
Current database:
Current user:       root@localhost
SSL:            Not in use
Current pager:      stdout
Using outfile:      ''
Using delimiter:    ;
Server version:     5.7.19-0ubuntu0.16.04.1 (Ubuntu)
Protocol version:   10
Connection:     Localhost via UNIX socket
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    utf8
Conn.  characterset:    utf8
UNIX socket:        /var/run/mysqld/mysqld.sock
Uptime:         1 min 16 sec

可以看到db和server的characterset都默认为latin1,这里需要设置[mysqld]的character-set-server = utf8即可

//mysql.cnf
[mysqld]
character-set-server = utf8

然后重启mysql服务,在命令行输入

service mysql restart

然后重新查看,可以看到mysql的默认编码已经改过来了。

如果你不想这么麻烦,可以在创建数据库的时候设置编码为utf8即可
如下命令

CREATE DATABSE db_name DEFUALT CHARACTER SET utf8;

下面在django中配置mysql

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blog',
        'USER': 'root',
        'PASSWORD': '',
        'HOST':'',
        'PORT':'',
    }
}

这里由于我的mysql用户没有设置密码所以,password为空,后续再进行设置
先需要在mysql中创建数据库。

CREATE DATABASE blog;

这个时候django还没有和mysql连接起来,需要安装mysqlclient或者MySQL-python,我在这里安装的是mysqlclient,在安装mysqlclient之前还需要安装libmysqlclient-dev

sudo apt-get install libmysqlclient-dev
pip install mysqlclient

这个时候就可以用django的数据迁移

python manage.py makemigrations
python manage.py migrate

这个时候进入mysql命令行,查看blog数据库中是否插入了django数据迁移来的数据库表

mysql> use blog
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------------------+
| Tables_in_blog             |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

看到数据库中的表就可以指导mysql已经配置完成了。
这样SkyNet的服务器配置基本上就完成了。后面需要解决一下代码上传和nginx等优化的问题。

配置nginx uwsgi部署Django项目

概念

  • Nginx:
    是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势

  • uwsgi:
    是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

  • 运行过程:
    nginx作为服务器的最前端,它将接受WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是nginx的强项,静态文件像我们django博客项目中的static文件夹下面的图片,css,js)。然后nginx将所有的非静态请求(像显示文章的详细信息,通常这类信息都保存在数据库,因此需要调用数据库获取数据)通过uwsgi传递给Django,由django来处理,从而完成一次WEB请求。uwsgi的作用就类似一个桥接器,起到桥梁的作用。

部署环境

阿里云服务器ubuntu14.04 (域名买了还没备案,所以博客暂时是通过ip访问的)

  • python3.5.2
  • nginx 1.4.6
  • uwsgi 2.0.15
  • django 1.11.3
  • markdown 1.0.1

一:安装nginx

打开putty远程控制云服务器输入账号和密码:

sudo apt-get install update 更新ubuntu库资源
sudo apt-get install nginx  安装nginx:
service nginx restart  启动nginx(重启)这个命令在后面要常用到

访问:http://59.110.155.51(这是我的云服务器的ip)

未分类

出现上图,则说明nginx启动成功

二:安装uwsgi

sudo apt-get install python3-pip
pip3 install uwsgi

测试uwsgi,创建test.py文件(注意:Linux创建目录的命令是:mkdir,创建test.py用 “vi test.py”命令)

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

函数名字application,这是默认的函数,uwsgi的Python加载器将会搜索这个名字
把它部署到htto端口8000(现在运行uwsgi来启动一个会把请求传递给你的wsgi应用的http服务器):

uwsgi --http :8000 --wsgi-file test.py

未分类

出现上图,则说明测试成功。

三:从github上获取django项目

sudo apt-get install git 安装git
git clone https://github.com/xuna123/Django_study1.git

四:安装django和markdwon:

pip3 install django
pip3 install markdown

五:将nginx+uwsgi部署到django博客项目

我们实现的目录:

未分类

在我们从Git拉下来Django_study1项目的时候,在子目录下回自动帮我们生成wsgi.py文件,所以我们只需要创建

myweb_uwsgi.ini配置文件。

vim myweb_uwsgi.ini

文件内容:

# Django-related settings

socket = :8000

# the base directory (full path)
chdir           = /root/Django_study1


# Django s wsgi file
module          = easyblog.wsgi

# process-related settings
# master
master          = true

# maximum number of worker processes
processes       = 4

# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true

文件意思:

    • socket :指定项目执行的端口号
    • chadir :指定项目的目录
    • module :可以这么来理解,对于- myweb_uwsgi.ini文件来说,与它的平级的有一个easyblog目录,这个目录下有一个wsgi.py文件
    • master :允许主线程存在(true)
    • processes:开启的进程数量(这里是开启4个进程)
    • vacuum :当服务器退出的时候自动清理环境,删除unix socket文件和pid文件

配置nginx:

接下来要做的就是修改nginx的配置文件,打开/etc/nginx/sites-available/default文件,删除所有内容,写入下面内容:

server {
    listen         8099;
    server_name    59.110.155.51
    charset UTF-8;
    access_log      /var/log/nginx/myweb_access.log;
    error_log       /var/log/nginx/myweb_error.log;

    client_max_body_size 75M;

    location / {
        include uwsgi_params;
        uwsgi_pass 59.110.155.51:8000;
        uwsgi_read_timeout 2;
    }
    location /static {
        expires 30d;
        autoindex on;
        add_header Cache-Control private;
        alias /Django_study1/blog/static;
     }
 }
  • listen 指定的是nginx代理uwsgi对外的端口号(这个要自己阿里云服务器的安全组中添加)

  • server_name : 服务器的名字,(因为暂时没有域名,就写的ip地址)

  • access_log :用来指定日志文件的存放路径

  • error_log :用来指定错误日志文件的存放路径

  • include uwsgi_params “一般来说,你只需包含uwsgi_params文件 (包含在nginx发行版本中),使用uwsgi_pass指令来设置uWSGI socket的地址。

  • uwsgi_pass 设置uwsgi服务器的协议和地址,协议可是uwsgi或suwsgi(uwsgi over ssl); 地址可以是ip地址,域名,和可选的端口。

  • uwsgi_read_timeout:指令的含义是如果视图函数处理的时间超时,uwsgi便会关闭连接,这个关闭只是针对Nginx这边的关闭,视图函数还会继续执行,处理完成后,视图函数那边会报IO写入。

  • expires 30d:意味着静态和媒体文件夹中的所有内容将在30天内由浏览器缓存,但不会删除任何内容,您将无需重新生成服务器中的任何内容。

  • autoindex on;启用目录流量, 默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间。

  • add_header Cache-Control private: HTTP协议的Cache -Control指定请求和响应遵循的缓存机制。private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器。

  • alias /Django_study1/blog/static; 静态文件的位置(暂时这么理解)

接下里还有 一部修改settings.py里面的8ALLOWED_HOSTS增加我们访问的ip,如下:

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

ALLOWED_HOSTS = ['localhost','59.110.155.51']

现在我们重启nginx 和uwsgi:

service nginx restart
uwsgi --ini myweb_uwsgi.ini

未分类

CentOS7系统安装uWSGI Nginx运行Django应用

1. 基础环境配置

先安装好基础环境

cd ~
sudo yum groupinstall "Development tools"
sudo yum install python34 python34-devel python34-pip
pip3 install virtualenv
virtualenv python34
source python34/bin/activate

测试python环境

python --version
pip --version

如果是python3.4的环境,至此python环境配置好了,如果有错,多用一下Google解决。

2. Nginx安装

参考Nginx官网的安装文档,建议新手使用yum安装,后续升级维护方便。

  • 首先要安装Nginx仓库,sudo vi /etc/yum.repos.d/nginx.repo添加以下内容:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=1
enabled=1
  • 下载Nginx的key文件,wget https://nginx.org/keys/nginx_signing.key
  • 安装key文件,sudo rpm –import nginx_signing.key
  • 安装Nginx,sudo yum install nginx
  • 测试Nginx,sudo nginx

3. uWSGI安装

从此往下都需要在Python34的虚拟环境下,检查自己是否在Python34虚拟环境下,不在的话执行source python34/bin/activate确认进入虚拟环境,执行pip install uwsgi安装uWSGI,测试uWSGI是否安装好。执行vi test.py输入一下内容保存:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

开启uWSGI服务,uwsgi –http :8000 –wsgi-file test.py,打开浏览器,输入(你的IP):8000看到Hello World代表web client到uWSGI到Python的连接正常。

4. Django配置

先执行pip install -r requirements.txt安装好Python包,正式部署前要配置好Django项目的配置(settings.py),修改一下项目:

DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1','localhost','(你的域名)']
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

然后记得执行一下语句:

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser # 创建超级用户
python manage.py collectstatic

然后执行python manage.py runserver测试Django项目运行是否正常。

5. uWSGI到Django配置

uwsgi --http :8000 --module (你的Djnago项目名).wsgi

打开浏览器测试(8000端口),如果Django项目运行正常,表示Web Client到uWSGI到Django运行正常。

vi uwsgi.ini添加以下内容并保存

[uwsgi]
socket = :8001
chdir= (你的Django项目地址)
wsgi-file = (你的Django项目地址下wsgi.py所在位置)
touch-reload = ~/reload # 如果reload文件有更改,重启uWSGI
module=(你的Django项目名称).wsgi
master=true
processes = 2 # 进程数
threads = 4 # 线程数
chmod-socket    = 664
chown-socket = (centos用户名):(centos组)
vacuum=true
pidfile = ~/tmp/uwsgi.pid #pid 文件位置

执行uWSGI –ini uwsgi.ini &运行uWSGI,如果Django项目有更改的话可以执行touch ~/reload重启uWSGI。

6. 配置Nginx

执行 sudo vi /etc/nginx/nginx.conf修改添加一下内容

# 注意,这只是nginx.conf中的一部分,其他内容不熟悉的话不要修改。

http {
    upstream django {
        server 127.0.0.1:8001;
    }

    server {
        listen       80;
        server_name  (你的域名地址);
        if ($host != 'www.willtunner.me' ) {
            rewrite ^/(.*)$ http://www.willtunner.me/$1 permanent;
        }   # 此处修改自动添加www

        charset utf-8;
        access_log  logs/host.access.log  main;

        location / {
            uwsgi_pass  django;
            include     /etc/nginx/uwsgi_params;
        }

        location /static/ {
            alias (你的Django项目static地址);
        }

        location /media/ {
            alias (你的Django项目media地址);
        }

        location ~ .*.txt$ {
            root (robots.txt所在地址);
        }
    }
}

当然Nginx虚拟主机配置最好使用include语法放置在其他文件夹下,多个虚拟主机比较好管理,这里我只有一个虚拟主机,故直接在这里修改了。

改好了之后执行sudo nginx -s stop和sudo nginx重新加载Nginx的配置。

没有出错的话,至此从Web Client到Nginx到uWSGi到Django的通路便建立好了。网站可以正常访问了。

Centos7安装配置Python3.6 Django virtualenv gunicorn supervisor环境

跟着网上的教程走发现行不通阿!好多都是写个大概,而且每人的环境都是有些许差异的,比如说权限问题阿,等等都会造成安装的失败

说明:本教程在你已经拥有Centos7系统,已经安装好nginx服务器,已经安装了Python3.6 Django virtualenv gunicorn supervisor的前提下进行

接下来开始了!

1、新建你的django项目,假设项目名为Hello

 django-admin.py startproject Hello

2、想好你需要的端口号,假设端口号为8001(下面的端口号均以8001来举例,你可以换成你所需要的端口号),接下来启动服务器看看能不能运行,分两种情况

2.1 如果你只是想在本地运行则

python manage.py runserver127.0.0.1:8001

2.2 如果你想要外网也可以访问则

python manage.py runserver0.0.0.0:8001

3、接下来在浏览器中输入 “服务器ip:8001” ,比如我服务器的公网IP为 192.163.189.166 则输入192.163.189.166:8001,可能会出现三种情况!

3.1 成功运行

3.2 出现 DisallowedHost at / Invalid HTTP_HOST header: ‘10.211.55.6:8001’. You may need to add u’10.211.55.6′ to ALLOWED_HOSTS. 类似错误,解决方法:
进入项目目录下的Hello目录(注意项目目录名是和该名称相同的,此Hello和manage.py同级打开setting.py将ALLOWED_HOSTS = []改为ALLOWED_HOSTS = [‘*’]

3.3 如果在确保地址输入正确,端口也正确的前提下浏览器出现了 Unable to connect 错误,那么很可能是你的Centos7没有开启8001端口号的原因,解决方法

开启端口号

firewall-cmd --zone=public --add-port=8001/tcp --permanent (--permanent意思是永久生效,重启后继续生效)

重启防火墙

firewall-cmd --reload

此时再访问浏览器,如果还是访问不了,那可能是我没遇到的情况,还请自行搜索解决哦

4、配置virtualenv gunicorn

4.1 在项目根目录下输入指令 virtualenv venv (venv可以是其他名字了)

4.2 虚拟环境生成后接着要在虚拟环境中安装django 和 gunicorn 了

pip install django
pip install gunicorn

4.3 在项目根目录下创建gunicorn.conf 用来配置gunicorn,我的配置为

workers = 4
bind = '0.0.0.0:8088'

5、配置supervisor

supervisor的配置文件一般在/etc/supervisord.conf

5.1 vim /etc/supervisord.conf

5.2 在末尾加入

[program:hello]
command=/项目路径/venv/bin/gunicorn -c /项目路径/gunicorn.conf Hello.wsgi:application
directory=/项目路径
autostart=true
autorestart=true
stdout_logfile=/项目路径/logs/gunicorn.log
stderr_logfile=/项目路径/logs/gunicorn.err  

5.3 重启 supervisor

unlink /tmp/supervisor.sock
supervisord -c /etc/supervisord.conf

6、配置nignx

6.1 打开nignx.conf

6.2 在合适地方加入

location /  {
     proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
     proxy_set_header Host $http_host;
     proxy_redirect off;
     proxy_pass http://192.163.189.166:8001;   #http://外网ip:8001,如果是本机访问则
http://127.0.0.1:8001
              }

6.3 重启nginx

systemctl restart nginx

7、好啦,接下来在浏览器中输入 http://192.163.189.166:8001 应该能访问咯。