Ubuntu 16.04 上使用Nginx骚勘、 Gunicorn铐伴、supervisor 部署django項(xiàng)目

本文記錄Ubuntu 16.04 上使用Nginx、 Gunicorn俏讹、supervisor 部署django項(xiàng)目

準(zhǔn)備工作:

  • Ubuntu16.04安裝Python3.6

Ubuntu16.04默認(rèn)安裝了Python2.7和3.5当宴,但是我的項(xiàng)目是在mac系統(tǒng)調(diào)試完成,而mac系統(tǒng)安裝了python3.6泽疆,為了兩端保持調(diào)試一直户矢,我決定把ubuntu上的python升級到3.6
請注意,系統(tǒng)自帶的python千萬不能卸載殉疼!

sudo add-apt-repository ppa:jonathonf/python-3.6
sudo apt-get update
sudo apt-get install python3.6
sudo apt-get install python3.6-dev

調(diào)整Python3的優(yōu)先級梯浪,使得3.6優(yōu)先級較高捌年,python3的默認(rèn)版本就是python3.6

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.5 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 2

更改默認(rèn)值,python默認(rèn)為Python2驱证,現(xiàn)在修改為Python3延窜,但是不建議更改

sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 100
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 150

如果需要通過pip命令單獨(dú)為python3安裝某些包恋腕,可不必修改系統(tǒng)默認(rèn)的python環(huán)境抹锄,我們安裝pip3 即可

sudo apt-get install python3-pip

安裝完成后,通過pip3安裝即可

注意:如果已經(jīng)安裝了python3.6后荠藤,安裝python3.6-dev時伙单,各種報(bào)錯,請升級python3.6.

  • 創(chuàng)建一個django項(xiàng)目

我的項(xiàng)目托管在github哈肖,配置在新的服務(wù)器時吻育,通過git clone即可,這里把項(xiàng)目clone在/var/www目錄下淤井,這里放所有web項(xiàng)目的根目錄布疼。
更改/var/www權(quán)限為www-data,以免每次都是用root權(quán)限去操作/var/www目錄

  • 更改/var/www目錄權(quán)限為www-data
    首先币狠,確保我的用戶名包含在 www-data 組中游两。 如果沒有,你可以將你的用戶名添加為 www-data 組
sudo adduser $USER www-data

之后漩绵,你應(yīng)該將/var/www的所有權(quán)更改為你的用戶名

sudo chown $USER:www-data -R /var/www

下一步贱案,對于常規(guī)實(shí)踐,你應(yīng)該更改權(quán)限為 755 ( rwxr-xr-x )止吐,而不建議將權(quán)限更改為 777宝踪,因?yàn)榘踩栽?/p>

sudo chmod u=rwX,g=srX,o=rX -R /var/www

下面是設(shè)置前后的權(quán)限截圖


屏幕快照 2019-04-23 上午10.15.35.png
  • 創(chuàng)建一個python3虛擬環(huán)境
mkvirtualenv -p /usr/bin/python3 blogapi
  • 激活虛擬環(huán)境
    這里跳過準(zhǔn)備工作,假設(shè)我已經(jīng)有了一個項(xiàng)目DjangoBlog和一個虛擬環(huán)境alpfaceblog

創(chuàng)建數(shù)據(jù)庫

登錄mysql創(chuàng)建一個數(shù)據(jù)庫,這里創(chuàng)建一個名稱為blog數(shù)據(jù)庫:

mysql -uroot -p
create database blog charset=utf8;

配置DjangoBlog/setting.py 中數(shù)據(jù)庫 相關(guān)配置碍扔,如下所示:

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

安裝配置gunicorn

  • 首先切換到項(xiàng)目的虛擬環(huán)境
workon alpfaceblog
  • 創(chuàng)建數(shù)據(jù)庫
python manage.py makemigrations
python manage.py migrate
  • 創(chuàng)建超級用戶
python manage.py createsuperuser
  • 收集靜態(tài)文件
python manage.py collectstatic --noinput
python manage.py compress --force
  • 在虛擬環(huán)境中安裝gunicorn
pip install django gunicorn
  • 把 gunicorn 加入項(xiàng)目settings.py中的 INSTALLED_APPS
INSTALLED_APPS = (
    # ...
    'gunicorn',
)
  • 測試gunicorn是否可以正常工作
cd /var/www/Blog
sudo gunicorn -b 0.0.0.0:8888 --worker-class=gevent DjangoBlog.wsgi:application
  • 配置生產(chǎn)環(huán)境下的gunicorn
    創(chuàng)建一個bash腳本用于快速啟動gunicorn的
    在項(xiàng)目目錄下創(chuàng)建一個文件夾bin瘩燥,然后創(chuàng)建gunicorn_start文件
sudo vim  gunicorn_start

添加以下內(nèi)容,注意路徑需要根據(jù)實(shí)際情況替換

#!/bin/bash

NAME="DjangoBlog" # 項(xiàng)目的名稱
DJANGODIR=/var/www/Blog # 項(xiàng)目所在的目錄
SOCKFILE=/var/www/Blog/run/gunicorn.sock # 啟動gunicorn.sock使用UNIX套接字
USER=root # the user to run as
GROUP=root # the group to run as
NUM_WORKERS=3 # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=DjangoBlog.settings # which settings file should Django use
DJANGO_WSGI_MODULE=DjangoBlog.wsgi # WSGI module name

echo "Starting $NAME as `whoami`"

# 啟動虛擬環(huán)境的路徑
cd $DJANGODIR
source /home/parallels/.virtualenvs/alpfaceblog/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Start your Django Unicorn
# gunicorn 安裝在虛擬環(huán)境下的完整路徑
exec /home/parallels/.virtualenvs/alpfaceblog/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--bind=unix:$SOCKFILE \
--log-level=debug \
--log-file=-


添加可執(zhí)行權(quán)限: sudo chmod u+x bin/gunicorn_start
啟動gunicorn

 ./bin/gunicorn_start
  • 查看給項(xiàng)目配置的gunicorn_start是否啟動了項(xiàng)目
sudo pstree -ap|grep gunicorn

如果顯示有進(jìn)程,則說明已經(jīng)啟動不同,如下:

root@ubuntu:/etc/supervisor# sudo pstree -ap|grep gunicorn
  |   |   |   |   |           |-grep,16796 --color=auto gunicorn
  |   `-gunicorn,16776 /home/parallels/.virtualenvs/blogapi/bin/gunicorn BlogApi.wsgi:application --nameB
  |       |-gunicorn,16781 /home/parallels/.virtualenvs/blogapi/bin/gunicorn BlogApi.wsgi:application --nameB
  |       |-gunicorn,16785 /home/parallels/.virtualenvs/blogapi/bin/gunicorn BlogApi.wsgi:application --nameB
  |       `-gunicorn,16787 /home/parallels/.virtualenvs/blogapi/bin/gunicorn BlogApi.wsgi:application --nameB

此時可以通過瀏覽器訪問試試

  • 關(guān)閉gunicorn 進(jìn)程
sudo kill -9 上面查詢的第一個pid

如果配置了supervisor管理gunicorn進(jìn)程啟動颤芬,則會在殺死后自動重啟

安裝并配置supervisor

Superviosr是一個進(jìn)程監(jiān)管的工具。簡而言之套鹅,Superviosr可以保證你的程序在服務(wù)器開機(jī)時自動啟動以及程序意外終止時重新啟動站蝠。

  • 安裝
sudo apt-get install supervisor
  • 配置

supervisor的配置文件默認(rèn)從/etc/supervisor/conf.d中讀取

cd /etc/supervisor/conf.d

創(chuàng)建并編輯一個supervisor的配置文件

sudo vim alpfaceblog.conf 

添加下面內(nèi)容,注意路徑需要根據(jù)實(shí)際情況替換

[program:DjangoBlog]
command = /var/www/Blog/bin/django_start
user = root
autostart=true
autorestart=true

redirect_stderr = true
stdout_logfile = /root/logs/blog/robot.log
stderr_logfile=/root/logs/blog/err.log  

手動創(chuàng)建日志目錄:

mkdir -p /root/logs/blog

通過supervisorctl工具來啟用這些設(shè)置:

sudo supervisorctl update
sudo supervisorctl reload  

啟動

supervisord -c /etc/supervisor/supervisord.conf 

查看supervisord進(jìn)程

ps aux | grep supervisord 

查看日志卓鹿,是否啟動

cat /tmp/supervisord.log 

每次修改配置文件后需進(jìn)入supervisorctl菱魔,執(zhí)行reload。 supervisord : supervisor的服務(wù)器端部分吟孙,用于supervisor啟動 supervisorctl:啟動supervisor的命令行窗口澜倦,在該命令行中可執(zhí)行start聚蝶、stop、status藻治、reload等操作碘勉。

這里我遇到了Supervisor啟動錯誤信息:

  • 問題1:
pkg_resources.DistributionNotFound: The 'supervisor==3.2.0' distribution was

解決方法:
這是由于我把ubuntu的python默認(rèn)環(huán)境改成3.5的了,其實(shí)再改回2.7就好了

切換Python版本
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 200
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 100
  • 問題2:
    supervisor 執(zhí)行 django項(xiàng)目中的gunicorn_start失敗
    解決步驟:
查看`/var/log/supervisor/supervisord.log`桩卵,錯誤為: `exit status 127; not expected`

查詢suspervisord配置的項(xiàng)目日志/root/logs/blogapi/robot.log顯示以下錯誤

supervisor: couldn't exec /var/www/blogapi/bin/gunicorn_start: ENOEXEC

解決方法:
stackoverflow中找到了答案验靡,在項(xiàng)目的gunicorn_start文件頂部添加#!/bin/sh,其實(shí)我添加的是#!/bin/bash雏节,我將它改為#!/bin/sh胜嗓,再次執(zhí)行sudo supervisorctl reload 問題解決。

  • 問題3:
    執(zhí)行sudo supervisorctl update 時報(bào)錯:root@ubuntu:/var/www/blogapi# sudo supervisorctl update error: <class 'xmlrpclib.Fault'>, <Fault 92: "CANT_REREAD: The directory named as part of the path /root/logs/blogapi/robot.log does not exist. in section 'program:BlogApi' (file: '/etc/supervisor/conf.d/blogapi.conf')">: file: /usr/lib/python2.7/xmlrpclib.py line: 800
    解決方法:
    啟動supervisord
 supervisord -c /etc/supervisor/supervisord.conf
  • 問題4:
    每次supervisord reload 或者 啟動 都會報(bào)錯:
Error: The directory named as part of the path /root/logs/blogapi/robot.log does not exist. in section 'program:BlogApi' (file: '/etc/supervisor/conf.d/blogapi.conf')

解決方法:
出現(xiàn)這個錯誤钩乍,是提示/root/logs/blogapi/robot.log文件不存在辞州,查看下/root/logs/blogapi/目錄確實(shí)不存在,創(chuàng)建mkdir /root/logs/blogapi/寥粹,然后重新啟動或者reload即可

安裝并配置nginx

  • 安裝nginx
sudo apt-get install nginx
  • ubantu安裝完Nginx后变过,文件結(jié)構(gòu)大致為:
    • 所有的配置文件都在 /etc/nginx下;
    • 啟動程序文件在 /usr/sbin/nginx下涝涤;
    • 日志文件在 /var/log/nginx/下媚狰,分別是access.log和error.log;
    • 并且在 /etc/init.d下創(chuàng)建了啟動腳本nginx妄痪。

以下為nginx常用的命令

sudo /etc/init.d/nginx start    # 啟動
sudo /etc/init.d/nginx stop     # 停止
sudo /etc/init.d/nginx restart  # 重啟
  • 配置nginx

配置Nginx 為我們的Django應(yīng)用創(chuàng)建一個配置文件/etc/nginx/sites-available/alpfaceblog.conf

sudo vim alpfaceblog.conf

刪除/etc/nginx/sites-available中default文件哈雏,/etc/nginx/sites-enabled中的default軟連接也一并刪除,不然瀏覽器訪問的可能是nginx的默認(rèn)頁面衫生。

添加以下內(nèi)容裳瘪,注意:如果配置多個項(xiàng)目的nginx conf文件時,conf中的upstream 名稱(my_server)不要重復(fù)罪针,不然nginx啟動時會報(bào)錯

upstream my_server {
    server unix:/var/www/Blog/run/gunicorn.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    large_client_header_buffers 4 16k;
    client_max_body_size 300m;
    client_body_buffer_size 128k;
    proxy_connect_timeout 600;
    proxy_read_timeout 600;
    proxy_send_timeout 600;
    proxy_buffer_size 64k;
    proxy_buffers   4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;

    root /var/www/Blog;

    keepalive_timeout 70;
    access_log /var/log/nginx/django_access.log;
    error_log /var/log/nginx/django_error.log;

    location /static {
          expires max;
          alias /var/www/Blog/collectedstatic/;
    }

    location /media  {
        alias /var/www/Blog/media/;
    }
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        if (!-f $request_filename) {
            proxy_pass http://my_server;
            break;
        }
    }

}
   

  • 讓nginx的配置文件生效
 sudo ln -s  /etc/nginx/sites-available/alpfaceblog.conf   /etc/nginx/sites-enabled/alpfaceblog.conf
  • 重啟nginx服務(wù)器
sudo service nginx restart
  • nginx 配置多個域名訪問不同的項(xiàng)目
    在不同的nginx conf文件下彭羹,添加server_name 為不同的域名,并設(shè)置listen 為同一斷開80泪酱,
    比如weather.conf
server {
    listen 80;
    server_name enba.com;
    .....
}

再比如blog.conf

server {
    listen 80;
    server_name objc.com;
    .....
}
  • 當(dāng)項(xiàng)目的nginx conf文件配置完成完成派殷,nginx運(yùn)行正常且可reload,但是就是無法通過瀏覽器訪問時墓阀,此時要檢查sites-available下的.conf文件命名是否為.conf結(jié)尾毡惜,另外還有sites-enabled下的軟連接文件是否正常或者為.conf結(jié)尾斯撮。
  • 當(dāng)在sites-available中刪除某個.conf文件時经伙,sites-enabled下的軟連接也要刪除,進(jìn)入到sites-enabled目錄下勿锅,rm -rf 即可帕膜。

問題:

nginx遇見的問題

1.最近在訪問部分頁面時枣氧,速度經(jīng)常非常慢,導(dǎo)致報(bào)502 Bad Gateway錯誤
解決方法:
查看nginx的錯誤日志垮刹,我是配置在error_log /var/log/nginx/django_error.log;

日志中我發(fā)現(xiàn)了兩個問題达吞,第一個問題:

ubuntu@ip-172-31-17-237:/var/log/nginx$ cat django_error.log
2018/02/24 09:10:43 [error] 1132#1132: *72 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 66.249.64.22, server: www.alpface.com, request: "GET /article/2018/1/20/1.html HTTP/1.1", upstream: "http://unix:/var/www/Blog/run/gunicorn.sock/article/2018/1/20/1.html", host: "www.alpface.net"
2018/02/24 09:22:42 [error] 1132#1132: *87 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 222.249.170.75, server: www.alpface.com, request: "POST /admin/blog/article/add/ HTTP/1.1", upstream: "http://unix:/var/www/Blog/run/gunicorn.sock/admin/blog/article/add/", host: "alpface.com", referrer: "http://alpface.com/admin/blog/article/add/"

通過網(wǎng)友的各種嘗試,我決定試一試荒典,最終解決了酪劫,解決方法:
這是由于,NGINX反向代理的超時報(bào)錯:

ubuntu@ip-172-31-17-237:/var/log/nginx$ cd /etc/nginx/sites-available/
ubuntu@ip-172-31-17-237:/etc/nginx/sites-available$ sudo vi alpfaceblog.conf 

在網(wǎng)站的配置文件中添加以下种蝶,并重啟nginx

server {  
        listen       80;  
        server_name  localhost;  
          
        large_client_header_buffers 4 16k;  
        client_max_body_size 300m;  
        client_body_buffer_size 128k;  
        proxy_connect_timeout 600;  
        proxy_read_timeout 600;  
        proxy_send_timeout 600;  
        proxy_buffer_size 64k;  
        proxy_buffers   4 32k;  
        proxy_busy_buffers_size 64k;  
        proxy_temp_file_write_size 64k;  
  
        #.............................  
    }  

重啟:sudo /etc/init.d/nginx restart

第二個問題:
查看錯誤日志可以看到:/var/www/Blog/media//, media后面多了一個/, 這是由于nginx配置文件中的資源文件路徑寫錯了導(dǎo)致的契耿,修改下我的配置文件瞒大,重啟nginx解決螃征;

ubuntu@ip-172-31-17-237:/var/log/nginx$ cat django_error.log
2018/03/05 06:44:04 [error] 3493#3493: *1 upstream prematurely closed connection while reading response header from upstream, client: 222.249.170.75, server: localhost, request: "GET /article/2018/2/28/38.html HTTP/1.1", upstream: "http://unix:/var/www/Blog/run/gunicorn.sock:/article/2018/2/28/38.html", host: "www.alpface.com", referrer: "http://www.alpface.com/login/?next=/article/2018/2/28/38.html"
2018/03/05 06:51:16 [error] 3493#3493: *33 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/article/edit/?aid=32"
2018/03/05 06:51:26 [error] 3493#3493: *32 open() "/var/www/Blog/collectedstatic//blog/img/favicon.ico" failed (2: No such file or directory), client: 222.249.170.75, server: localhost, request: "GET /static/blog/img/favicon.ico HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/article/edit/?aid=32"
2018/03/05 06:56:05 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/article/list/"
2018/03/05 06:56:09 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/message/comment/"
2018/03/05 06:56:11 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/message/os/"
2018/03/05 06:56:12 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/message/comment/"
2018/03/05 06:56:15 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/visitor/"
2018/03/05 06:56:18 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/link/"
2018/03/05 06:56:23 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/profile/"
2018/03/05 06:56:37 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/profile/"
2018/03/05 06:56:40 [error] 3493#3493: *41 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/profile/"
2018/03/05 06:56:41 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/link/"
2018/03/05 06:56:43 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/profile/"
2018/03/05 06:56:45 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/article/add/"
2018/03/05 06:56:52 [error] 3493#3493: *39 directory index of "/var/www/Blog/media//" is forbidden, client: 222.249.170.75, server: localhost, request: "GET /media/ HTTP/1.1", host: "www.alpface.com", referrer: "http://www.alpface.com/admin/"
執(zhí)行數(shù)據(jù)庫遷移時遇見的問題
  1. 當(dāng)修改或新增model後, 執(zhí)行python manage.py makemigrations,未生成遷移:
    解決方法:
    刪除每個app文件下migrations文件中除了init.py的所有文件,然後再執(zhí)行python manage.py makemigrations重新生成遷移

  2. 數(shù)據(jù)庫遷移時遇見的問題:
    錯誤信息:

django.db.utils.InternalError: (1054, "Unknown column 'name' in 'django_content_type'")

解決方法:
在數(shù)據(jù)庫中手動添加沒有創(chuàng)建的字段

alter table django_content_type add column name varchar(10)
  1. 遷移數(shù)據(jù)庫python manage.py migrate時出錯:
django.db.utils.InternalError: (1050, "Table 'auth_permission' already exists")

解決方法:

python manage.py migrate --fake

但是此種方法會忽略一些錯誤,導(dǎo)致最終還是不能解決我們的遷移的問題

  • ModuleNotFoundError: No module named 'apt_pkg'

升級到python3.6會導(dǎo)致python庫的引用產(chǎn)生混亂憎茂,然后python3的軟鏈接也被我改成指向最新版本了谅猾。

解決方法:
先選擇刪除python-apt

apt-get remove --purge python-apt 

安裝python-apt

apt-get install -f -y python-apt

拷貝python3.5的apt-pkg.so 名重名為python3.6的apt-pkg.so

cd /usr/lib/python3/dist-packages/ 
sudo cp apt_pkg.cpython-3?m-x86_64-linux-gnu.so apt_pkg.cpython-36m-x86_64-linux-gnu.so 

總結(jié):
我的blog項(xiàng)目是在我的本地電腦ubuntu系統(tǒng)上開發(fā)並測試的,然後提交到github上,最後部署到亞馬遜服務(wù)器時,通過git命令clone到服務(wù)器上;
期間我在本地修改或創(chuàng)建了一些model,這時我在本地生成遷移和遷移時都沒有,但是在服務(wù)端遷移總是報(bào)錯,導(dǎo)致遷移失敗;
原因:在網(wǎng)上查找各種資料最終都沒有解決,最後我發(fā)覺項(xiàng)目的.gitignore中忽略了migrations文件,而每次改變model或新增model時,都會生成一個000n_.py文件,每次改變n都會加1,
此時我的數(shù)據(jù)庫也會在遷移時發(fā)生改變,而當(dāng)我在服務(wù)器執(zhí)行遷移時,服務(wù)器端沒有migrations文件,每次遷移都會重新生成,那麼和本地執(zhí)行時機(jī)不同,所以會需要每次執(zhí)行遷移時,會根據(jù)migrations執(zhí)行的結(jié)果也不同;
解決方法:當(dāng)然我們可以在gitignore中取消這些忽略文件, 另外當(dāng)我們在服務(wù)器段執(zhí)行遷移遇到文件時,我們可以把本地的0001_initial.py中的復(fù)制到服務(wù)端對應(yīng)的這個文件再執(zhí)行python manage.py makemigrationspython manage.py migrate

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市趟薄,隨后出現(xiàn)的幾起案子酗电,更是在濱河造成了極大的恐慌魄藕,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撵术,死亡現(xiàn)場離奇詭異背率,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嫩与,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門寝姿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人划滋,你說我怎么就攤上這事饵筑。” “怎么了处坪?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵根资,是天一觀的道長。 經(jīng)常有香客問我同窘,道長玄帕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任想邦,我火速辦了婚禮裤纹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘案狠。我一直安慰自己服傍,他們只是感情好钱雷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吹零,像睡著了一般罩抗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灿椅,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天套蒂,我揣著相機(jī)與錄音,去河邊找鬼茫蛹。 笑死操刀,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的婴洼。 我是一名探鬼主播骨坑,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼柬采!你這毒婦竟也來了欢唾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粉捻,失蹤者是張志新(化名)和其女友劉穎礁遣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肩刃,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祟霍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盈包。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沸呐。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖续语,靈堂內(nèi)的尸體忽然破棺而出垂谢,到底是詐尸還是另有隱情,我是刑警寧澤疮茄,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布滥朱,位于F島的核電站,受9級特大地震影響力试,放射性物質(zhì)發(fā)生泄漏徙邻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一畸裳、第九天 我趴在偏房一處隱蔽的房頂上張望缰犁。 院中可真熱鬧,春花似錦、人聲如沸帅容。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并徘。三九已至遣钳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間麦乞,已是汗流浹背蕴茴。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姐直,地道東北人倦淀。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像声畏,于是被迫代替她去往敵國和親撞叽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容