友情提示:380元/半年,儿童学编程,就上码丁实验室。
上篇我们介绍了三种远程控制树莓派的方法,今天将把我部署在阿里云的Django项目迁移到树莓派上。
1. SSH登入到树莓派。
ssh pi@192.168.1.201
2. 新建一个名为app的目录,将项目源码checkout到app目录中。
mkdir app
cd app
git clone https://github.com/username/project_name
3. virtualenv。
- 因为我的树莓派的Python版本和这个Django项目的Python版本不一致,所以需要创建一个独立的Python运行环境,virtualenv就是用来创建隔离的Python环境的。
sudo pip3 install virtualenv
cd project_name
- 创建名为venv的运行环境,–no-site-packages表示原来的系统python环境不会复制过来,创建的环境是全新的。
virtualenv --no-site-packages venv
- 进入virtualenv,每次进入都需要使用这个命令,退出环境使用deactivate。
source venv/bin/activate
- 在~/.bashrc文件最后加上以下代码以确保pip3安装的时候将packages安装到virtualenv中而不是系统中,然后退出SSH再重新登入树莓派并进入virtualenv。
vi ~/.bashrc
# add this line to ~/.bashrc.
export PIP_REQUIRE_VIRTUALENV=true
cd app/project_name
source venv/bin/activate
4. Django项目依赖。
- 安装Django项目的所有依赖(可选,如果是新项目就不需要安装)。
sudo pip3 install xxxxx
...
sudo apt-get install xxxx
...
- 查看pip3安装了哪些依赖。
pip3 freeze # show installed packages in requirements format
pip3 list # show all installed packages
pip3 freeze --all == pip list
pip3 freeze > requirements.txt # output all requirements to file
5. 安装数据库。
- 数据库我们使用的是Django官方推荐的postgresql
sudo apt-get install postgresql-9.6 postgresql-server-dev-9.6
# vi /etc/postgresql/9.6/main/pg_hba.conf
# (Change all authentication mechanisms from ident to md5)
sudo /etc/init.d/postgresql reload
- 创建账号和数据库
# switch to postgres account
(venv) pi@raspberrypi:~/app/backend $ sudo su - postgres
# create postgres user
postgres@raspberrypi:~$ createuser pi
# create database
postgres@raspberrypi:~$ createdb backend
# sql environment
postgres@raspberrypi:~$ psql
# add password for user
postgres=# ALTER USER pi WITH PASSWORD '123456';
ALTER ROLE
# make user superuser
postgres=# ALTER ROLE pi WITH SUPERUSER;
ALTER ROLE
# add create roll permission
postgres=# ALTER ROLE pi WITH CREATEROLE;
ALTER ROLE
# logout
postgres-# q
postgres@raspberrypi:~$ exit
logout
- 从原来服务器导出数据,database为你的数据库名称。(可选,如果是新项目就不需要)
pg_dump <database> > dump.sql
- 导入到当前数据库(可选,如果是新项目就不需要)
(venv) pi@raspberrypi:~/app/backend/sqls $ psql -U pi backend < dump.sql
- settings.py设置数据库信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'backend',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '',
}
}
6. 现在运行Django,并在树莓派运行localhost:8000/admin就会出现如下画面了。
(venv) pi@raspberrypi:~/app/backend $ python manage.py runserver

7. Apache2。
- 复制static文件
python manage.py collectstatic
- 修改backend/wsgi.py如下
import os
import sys
#sys.path.append('/home/pi/app/backend/venv/lib/python3.5/site-packages/')
# add your project directory to the sys.path
project_home = u'/home/pi/app/backend'
if project_home not in sys.path:
print(project_home)
sys.path.append(project_home)
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "backend.settings")
application = get_wsgi_application()
from os.path import dirname,abspath
PROJECT_DIR = dirname(dirname(abspath(__file__)))
sys.path.insert(0, PROJECT_DIR)
- 安装Apache2
sudo apt-get install apache2 libapache2-mod-wsgi3
- 如果安装的时候提示找不到libapache2-mod-wsgi3,请使用以下命令
sudo apt-get install apache2 libapache2-mod-wsgi-py3
- 添加并编辑配置文件
cd /etc/apache2/sites-available
sudo cp 000-default.conf backend.conf
sudo vi backend.conf
- 配置文件内容,使用绝对路径
<VirtualHost *:8000>
WSGIScriptAlias / /home/pi/app/backend/backend/wsgi.py
# for virtaulenv
WSGIDaemonProcess myproject python-home=/home/pi/app/backend/venv python-path=/home/pi/app/backend
# for virtaulenv
WSGIProcessGroup myproject
DocumentRoot "/home/pi/app/backend"
# mkdir /home/pi/app/backend/static if not exists.
Alias /static/ /home/pi/app/backend/static/
# mkdir /home/pi/app/backend/media if not exists.
Alias /media/ /home/pi/app/backend/media/
# mkdir /home/pi/app/backend/logs if not exists.
ErrorLog "/home/pi/app/backend/logs/error_log"
CustomLog "/home/pi/app/backend/logs/access_log" common
<Directory "/home/pi/app/backend/backend">
Require all granted
</Directory>
<Directory "/home/pi/app/backend/static">
Require all granted
</Directory>
<Directory "/home/pi/app/backend/media">
Require all granted
</Directory>
</VirtualHost>
- 因为需要将Apache和Django进行绑定,所以需要将端口更改为它们共有的
sudo vi /etc/apache2/ports.conf
# add this two line to /etc/apache2/ports.conf
NamevirtualHost *:8000
Listen 8000
- /etc/apache2/apache2.conf添加ServerName
sudo vi /etc/apache2/apache2.conf
# add this line to /etc/apache2/apache2.conf
ServerName 192.168.1.201
# ServerName localhost
# ServerName 127.0.0.1
- 启用配置文件并重新加载Apache2
# enable backend.conf
sudo a2ensite backend.conf
# reload apache2
sudo service apache2 reload
- 使默认配置失效,否则局域网内无法使用
sudo a2dissite 000-default.conf
- 重启Apache2
sudo /etc/init.d/apache2 restart
- 这样你在树莓派里运行192.168.1.201:8000/admin就会出现如下画面了。如果你只是在局域网内使用这个服务器的话到这步就可以结束了,如果需要做成被外网访问就需要添加动态域名了。

- 如果出现404 bad request错误,则需要将ip添加到backend/settings.py的ALLOWED_HOSTS
ALLOWED_HOSTS = ['localhsot', '127.0.0.1', '192.168.1.201']
- 如果出现如下错误,表示Apache2的默认用户名是www-data,我们需要将默认用户名改为pi并重启Apache2

sudo vim /etc/apache2/envvars
# 将APACHE_RUN_USER和APACHE_RUN_GROUP都改为pi
# export APACHE_RUN_USER=www-data
# export APACHE_RUN_GROUP=www-data
export APACHE_RUN_USER=pi
export APACHE_RUN_GROUP=pi
sudo /etc/init.d/apache2 restart
8. 动态域名。
- 进入no-ip网站创建账号然后通过邮箱激活并登入
- 登入以后进入https://my.noip.com,在Hostname这行输入你想添加的hostname,在Domain这行选择一个domain,如果已经注册了就换一个,点击Add Hostname添加hostname

- 创建完成后你将看到一条记录,点击Active进入域名详细列表。

- 点击画圈黄色字体进入配置。

- 点击Configure Now

- 选择你的域名(如果只有一个会默认选中)并点击Next Step

- 路由器我这边是TP-Link,设备选中Rasspberry pi

- 选中Yes并点击Next Step

- 点击Download DUC

- 这边我们选中Linux并点击Download Now

- 下载完客户端后解压并编译安装
tar vzxf noip-duc-linux.tar.gz
cd noip-2.1.9-1
make
sudo make install
- 安装过程中输入信息
# 输入no-ip账号
Please enter the login/email string for no-ip.com
myemail@gmail.com
#输入no-ip密码
Please enter the password for user
....*******
# no-ip客户端检查你路由器外部网址变化的间隔默认是30分钟,我们改为10分钟,因为国内ISP会每几天强制断线、更换IP,这时noip会短暂失效。
Please enter an update interval: [30]
(Increments in minutes that you want no-ip client to check if your router’s external dynamic IP address has changed and updates it accordingly.)
10
# 直接按回车
Do you wish to run something at successful update? [N] (y/N)
- 启动noip客户端,如果需要开机就启动,将下面这行添加到/etc/rc.local的exit 0这行前面
sudo /usr/local/bin/noip2
- 其它no-ip命令
sudo /usr/local/bin/noip2 -C # 重新配置一次
sudo /usr/local/bin/noip2 -S # 显示当前运行状态
- 安装完以后点击Next Step

- 在路由器设置端口转发,可以参考this guide这篇文章或者我之前写的文章3.0 安装Duck DNS,实现远程访问Home Assistant的第8条,我们在Apache2配置的是8000端口,所以我们转发外部8000端口到内部8000端口。设置完路由器以后我们点击Next Step

- 输入你转发的端口号并点击Check Port进行验证

- 如果显示Port xxx is not open说明你路由器端口转发还不正确需要重新配置。

- 如果显示Port xxx is open表示端口转发成功点击Next Step页面会显示配置成功

- 暂时还不知道什么原因,外网可以访问no-ip:8000这个网址了,但是本地网络内的设备还是只能使用192.168.1.201:8000来访问这个服务器,之后知道原因以后将会更新。
这样我们就将原来在阿里云的服务器迁移到自己的树莓派上了。