Django + Nginx + phpmyadmin

1.關於

最近用到(其實已經不是最近了,這篇草稿存了一年)python做Web Application,使用框架則是Django,然而在使用Django的時候操作MySQL資料庫時雖然Django有提供admin管理介面,但坦白說,還是phpmyadmin來的比較好用,而在部屬Django的時候又因為有使用websocket的需求,故無法使用Apache進行部屬(有人知道怎麼用Apache + Django + Channels的話請分享一下),所以選擇了Nginx進行Web Service。

 

以下!因為過程有點攏長,我也是一邊Google一邊部屬,一邊紀錄,又因為Linux環境各所有差異,所遇到的問題千奇百怪,所以當部屬出現問題時,歡迎提出,但是我不一定能夠解答,因為我不一定會跟你遇到相同問題。

但是問題多半是,打錯字,路徑錯誤,權限錯誤。先朝這三個方向找,很多問題都可以解決。

2.Why?

在實作的過程中參考了很多國內外的資料,一方面來說,都是邊猜邊做,從A看到什麼,但是又缺了什麼,再從B看到A沒有的,東湊西湊,湊出一個可以用的東西,最近老了,很多事情記不住,趁現在還記的住的情況下,留下這篇文章作為以後老人癡呆的回憶。

3.正文開始

等等,正文開始前,我使用的相關程式版本如下:

Ubuntu 16.04.2 LTS

MySQL 5.7.17-0ubuntu0.16.04.1 - (Ubuntu)

Nginx 1.10.0

PHP  7.0.15-0ubuntu0.16.04.4

phpMyAdmin 4.5.4.1deb2ubuntu2

Python 3.5.3

Django 1.11.0

好了!我們開始

3.1 Python虛擬機器(環境)

首先我們必須建立一個Python虛擬機器,虛擬機器光要講可能又可以寫一堆東西,簡言之,使用Python虛擬機器可以帶來以下好處

a.方便管理相關模組(組件、套件)

b.專案再轉移的時候比較不會東漏西漏缺少相關模組(組件、套件)

c.在部屬上會來的比較簡單

現在我們在設備上選擇一個吉位來建立我們的專案目錄,例如我是在家目錄建立了一個myDjango

jed@ubuntu:~$ mkdir myDjango

建立完專案目錄後讓我們移動到專案目錄下,進行虛擬機器的建立

jed@ubuntu:~$ cd myDjango
jed@ubuntu:~/myDjango$ python3 -m venv my_venv
jed@ubuntu:~/myDjango$ ls -al
total 12
drwxrwxr-x   3 jed jed 4096 Apr 23 21:51 .
drwxr-xr-x  21 jed jed 4096 Apr 23 21:35 ..
drwxrwxr-x   6 jed jed 4096 Apr 23 21:50 my_venv

經過了短暫的廝殺,我們終於建立出了虛擬機器,讓我們進入虛擬機器中運行吧!

jed@ubuntu:~/myDjango$ . my_venv/bin/activate
(my_venv) jed@ubuntu:~/myDjango$ 

當看到前面多了(my_venv)之後就代表已經進入了虛擬機器的運作中了,再來讓我們來安裝Django

(my_venv) jed@ubuntu:~/myDjango$ pip install django
...以下省略當看到
Successfully installed django-1.11 pytz-2017.2

則代表安裝完成了

3.2建立Django專案

這個時候,Django已經安裝在虛擬機器了面了,我們可以透過Django來建立新的專案

(my_venv) jed@ubuntu:~/myDjango$ django-admin.py startproject helloNginx
(my_venv) jed@ubuntu:~/myDjango$ ls -al
...
...
drwxwxr-x   6 jed jed 4096 Apr 23 22:02 helloNginx
...

看到專案目錄已經透過Django初始化建立出來了,可喜可賀,這時候,我們先來設定一下host,讓Django變的超級不安全?

(my_venv) jed@ubuntu:~/myDjango$  vi helloNginx/helloNginx/settings.py

進行settings.py檔案修改如下

#settings.py
...
ALLOWED_HOSTS = ['*']
...

這個設定是讓Django專案接受所有IP連線,這時候呢我們就可以先來試試看Django是否可以正常Wrok了!

(my_venv) jed@ubuntu:~/myDjango$ python helloNginx/manage.py runserver 0.0.0.0:8000

此時可以透過瀏覽器開啟 http://host_ip:8000應該可以看到一個

It worked!
Congratulations on your first Django-powered page.

這代表Django已經可以正常服務了可喜可賀×2

3.3安裝Nginx

(my_venv) jed@ubuntu:~/myDjango$ sudo apt-get install nginx

透過apt-get安裝Nginx,安裝完成後透過瀏覽器開啟 http://host_ip則可看到

Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

稍後我們會部屬Django到Nginx讓Nginx接受http服務,並轉交給Django執行

3.4安裝MySQL + PHP + phpmyadmin

(my_venv) jed@ubuntu:~/myDjango$ sudo apt-get install mysql-server

透過apt-get安裝MySQL,安裝過程中會要求輸入MySQL root 帳號的密碼,請先記得該密碼。

如果安裝時沒出現在安裝完成後用以下命令指定新密碼

(my_venv) jed@ubuntu:~/myDjango$ sudo mysqladmin u root password

之後可以測試使用root帳號登入進去MySQL看是否可以正常登陸

(my_venv) jed@ubuntu:~/myDjango$ sudo mysql -u root -p

安裝PHP7

(my_venv) jed@ubuntu:~/myDjango$ sudo apt-get install -t stretch php7.0 php7.0-curl php7.0-gd php7.0-fpm php7.0-cli php7.0-opcache php7.0-mbstring php7.0-xml php7.0-zip

安裝phpmyadmin

(my_venv) jed@ubuntu:~/myDjango$ sudo apt-get install phpmyadmin

安裝phpmyadmin的時候他會要求選擇配置服務系統,這個選項我們必須先跳過

兩個都不要選直接TAB到OK

之後會詢問是否建立資料庫選擇 YES

下一步會要求輸入MySQL新帳號phpmyadmin密碼,就設定一個新密碼

之後就會開始自己安裝....

4部屬Django + phpmyadmin

部屬我們需要建立三個檔案,這邊名稱我取名如下

myDjango_nginx.conf、myDjango_uwsgi.ini、uwsgi_params

這兩個檔案請自行找地方存放,可以存放在Django專案目錄底下,比較方便管理

4.1 安裝uwsgi服務器

先在虛擬機器執行的環境下使用pip安裝uwsgi

(my_venv) jed@ubuntu:~/myDjango$ pip install uwsgi

安裝好之後就先不用裡他,之後Django執行會透過uwgi去啟動

安裝完發現沒有在虛擬機器裡面的話可以嘗試直接下載安裝

(my_venv) jed@ubuntu:~/myDjango$  pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz

4.2 uwsgi_params設定檔

這個檔案的內容可以是固定下面內容的原則上不需要去變更(不要問,很可怕),請自行複製以下內容建立檔案

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;

uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;

uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

4.3 .conf設定檔

這個myDjango_nginx.conf設定檔是給Nginx使用,也就是前端Http服務器會依據這個設定檔案內容進行服務指向,所以這邊我們會設定

a.phpmyadmin的指向

b.Django靜態目錄指向

檔案內容

#myDjango_nginx.conf
# the upstream component nginx needs to connect to
upstream django_myDjango {
    #自行替換unix://後面的路徑以及*.sock名稱
    server unix:///home/jed/myDjango/myDjango_uwsgi/myDjango.sock; # for a file socket
    #server 127.0.0.1:80; # for a web port socket (we'll use this first)
    
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

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

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    
    #自行更換Django media與static目錄絕對位置
    # Django media
    location /media  {
        alias /home/jed/myDjango/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /home/jed/myDjango/static; # your Django project's static files - amend as required
    }

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html index.php;
    #location 定義指向服務名稱可以自行變更設定,路徑需自行確認是否正確指向phpmyadmin網頁檔案目錄
    #將 /usr/share/phpmyadmin ln到/var/www/html底下
    #sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
    location /phpmyadmin {
        alias /var/www/html/phpmyadmin;
    }
    #這邊是設定.php服務器的內容
    location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php7.0-cgi alone:
                #fastcgi_pass 127.0.0.1:9000;
                # With php7.0-fpm:
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    # Finally, send all non-media requests to the Django server.
    # 這邊是設定 / 網址 就是入口網頁的指向,也就是我們必須把指向指到Django服務器裡面
    location /       {
        #uwsgi_params這個名稱設定要跟上面upstream django_myDjango {.....}的設定名稱一致
        uwsgi_pass  django_myDjango;
        #這個指向該檔案絕對路徑,請再自行修改對應存放路應
        include     /home/jed/myDjango/myDjango_uwsgi/uwsgi_params; # the uwsgi_params file you installed
    }

4.4 .ini設定檔

myDjango_uwsgi.ini這個檔案主要是用來配置uwsgi檔案內容的,配置內容請參考下面

[uwsgi]

# Django-related settings
# the base directory (full path)
#設定Django專案目錄的位置
chdir           = /home/jed/myDjango
# Django's wsgi file
module          = ezSolar.wsgi
# the virtualenv (full path)
#設定使用虛擬機的目錄位置
home            = /home/jed/myDjango/my_venv 

# process-related settings
# master
master          = true
#pidfile		=/tmp/project-master.pid
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
#這個socket檔案要跟配置Nginx的.conf設定是同一個!!
socket          = /home/jed/myDjango/myDjango_uwsgi/myDjango.sock
# ... with appropriate permissions - may be needed
#權限設定有些範例設定664,但我用664會有問題,所以我改666
chmod-socket    = 666
# clear environment on exit
vacuum          = true
#這個log檔案可以關閉,避免佔用空間
#daemonize	= /home/jed/myDjango/run.log
#這個buffer-size可以設定處裡Requeset Url的Buffer大小,預設4096當Buffer爆炸的時候,Request會被skip
buffer-size     = 8192

4.5 配置設定檔

三個檔案都準備好了之後,我們就開始進行檔案配置

4.5.1 配置 .conf 檔案給Nginx

sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/

將剛剛建立好的.conf檔案Link到nginx的sites-enabled資料夾內

配置完後重新啟動Ngingx,假設出現

[....] Starting nginx (via systemctl): nginx.serviceJob for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.
failed!

可以使用journalctl -xe查看錯誤訊息,通常是路徑有問題,從錯誤訊息中可以找到錯的位置

如果正常重新啟用,可以先試試看static或media中的檔案是否可以連結的到,如果找不到目錄中的既有檔案,可能也是路徑設定有問題。

再來試試看phpmyadmin能否正常工作連線,如果不能正常出現phpmyadmin畫面,多半還是路徑問題比較多。

4.5.2建立uwsgi的設定檔案

uwsgi主要是用來處理Django的服務程式,所以這邊如果設定有問題,就會造成Django無法正常運作

# 在etc目錄底下建立uwsgi/vassals資料夾
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# 將剛剛建立設定好的.ini檔案link到這個資料夾中
sudo ln -s /path/to/your/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/

4.6測試啟動

請先找到剛剛安裝的uwsgi位置

例如 /home/jed/.local/bin/uwsgi

然後用以下命令啟動服務

/home/jed/myDjango/my_venv/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data

啟動之後如果服務沒有正常有錯誤會顯示在螢幕上,請仔細debug找出錯誤的地方,如果正常的話Django就會正常work了

如果測試正常之後,可以將command加入啟動服務,讓開機之後自動執行,就可以上線囉!

加入開機服務的時候,要把uwsgi設定檔案目錄將權限交給www-data...否則uwsgi會無法啟動

PS.Django上線記得要把Debug mode關掉,要不然萬一出錯出現很多Debug訊息,是很可怕的。

2 thoughts on “Django + Nginx + phpmyadmin

發表迴響