零、前言
本博文记录搭建个人博客系统的完整过程,网上有许多相关的教程,但是没找到一个(适合自己能力的)快速搭建的完整教程。借此篇博文梳理一下前不久学习到的有关整个过程前前后后的各种知识点。
一、搭建环境
- 采用架构:python3.6 + django1.10 + nginx + uwsgi + mysql
- VPS平台:vultr
- VPS系统:Centos7 64位(5$/月,25G SSD,1CPU,1G内存,1000G流量/月,Los Angeles节点)
- 个人用的系统:Win7 64位
- 域名系统:godaddy
二、所需软件
- Win7 系统(自己操作所用的系统)
- SecureCRT 8.3 (用于远程VPS)
- FileZilla(用于Win7系统和VPS系统之间互传文件)
三、完整操作过程
因为是相对小白一点的操作过程,所以自己能够想到的细节都会记录
1、申请vultr账号
之所以推荐vultr,是因为我最初看搭建VPS的教程选择的就是vultr,在个人使用的过程中,vultr还算稳定,价格较国内的VPS便宜,可以搭建梯子,也不用绑定各种各样的身份验证,按时扣费,不用不扣。截止2018年11月5日,vultr已支持国内的支付宝和微信支付。
如果没有vultr账号,可按如下操作申请:
- 百度“vultr”,出现多个广告结果,下图是2018年11月5日的搜索结果,点开第一个链接显示的是第三方网站,点开第二个链接显示的是vultr的官方网站即 https://www.vultr.com/match/ ,个人推荐使用官方的推广链接(本人未做测试是否真能领取25$的赠送金额)。当初自己看教程创建账户的时候点的教程帖子中的优惠链接,充值10$后并未领取到25$,可能是优惠链接已过时。
- 另外,注册vultr账号设置的密码要求:10位字符或以上,包含英文大小写,特殊字符及数字
2、创建VPS
vultr充值完成后就可以创建VPS了,此处操作简单,就不配图了。
- 登录自己的vultr账号,点击左侧菜单栏的“Servers”,点击右侧蓝色“+”号进入创建页面,
- Server Location:国内大陆地区建议选择“Los Angeles”(洛杉矶)节点,据说相对其他节点ping值更低一些;
- Server Type:64 bit OS ----CentOS7 x64
- Server Size:此处个人选择的是5$/月的套餐,即25G SSD、1CPU、1G内存、1T流量,这个地方主要注意一个问题:不要选择2.5$/月的套餐,因为此套餐不给分配IPv4地址,只有IPv6地址,由于本次实验是用于映射域名需要用到IPv4地址(不知道IPv6咋玩…),因此避开此套餐即可;
- Additional Features:保持默认
- Startup Script:保持默认
- SSH Keys:保持默认
- Server Hostname & Label:此处写服务器的名字和标签,用于区分多个服务器,server hostname是在VPS系统中显示的 (注意此处不要命名为“localhost”,不然主机名会显示异常),server label是在vultr管理界面显示的;
- 最后再次检查以上各个配置,确认无误后点右下角的“Deploy Now”,等一会VPS即可生成,如下图VPS处于“Running”状态
3、使用VPS
-
点击右侧的三个点“···”,选择“View Console”,可进入登录页面(此处不建议用此方式登录,输入密码不方便),账号和密码可点击下图中的“Server Details”获取
账号及密码如下图:
-
打开本机上的SecureCRT软件,连接协议选择SSH2,输入VPS的ip地址、账号及密码进行远程。如果远程不上,ping 一下ip,不通则说明此ip已被墙,需要重新创建一个VPS,会另外分配一个ip地址,然后把之前的VPS销毁(如果先销毁再创建,因为时间间隔太短,可能新VPS的ip还是上个VPS的ip,当然也可以隔一段时间再建VPS,本次实验我创建了4个VPS才有一个可以远程连接T_T)
-
登录完第一件要做的事当然是修改root账号的密码啦,修改完密码记得做个系统快照。
4、环境部署 – 安装python3.6 & nginx & mysql 及虚拟环境
声明:本次实验是测试学习环境,登录的是root账户,生产环境应使用普通用户管理。
4.1 安装python3.6.6
-
用Win7系统打开python 下载官网 https://www.python.org/downloads/source/ ,找到对应版本的python,右键–复制链接地址,打开SecureCRT登录VPS,输入命令
wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz
即可把python安装包下载到linux系统;
-
也可以在Win7系统下载好安装包再上传到linux系统,使用软件工具“FileZilla”
打开FileZilla工具,点击 文件–站点管理器–新站点,协议选择 SFTP,主机写Linux系统的 ip地址,端口为 空,登录类型选择 正常,用户名密码写上Linux系统的登录账号密码,点击 连接
信任该主机,确定;
管理界面分为本地站点和远程站点,本地站点即本机(Win7系统),远程站点即VPS的linux系统。在此界面可以把本地的文件拖动到远程站点的文件目录中,即上传到linux;也可以把远程站点目录中的文件拖动到本地文件夹内。
- 本次下载的“Python-3.6.6.tgz”是源码安装包,安装方式如下:
yum install gcc -y
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel
cd ~/upload #先切换到Python-3.6.6.tgz安装包的目录
tar -xzvf Python-3.6.6.tgz
cd Python-3.6.6
./configure --prefix=/usr/local/python366/ #指定安装目录,便于后期卸载重装
make & make install
ln -s /usr/local/python366/bin/python3 /usr/bin/python3 # 设置软链
安装好python3.6.6后查看版本
[root@blog Python-3.6.6]# python -V
Python 2.7.5
[root@blog Python-3.6.6]# python3 -V
Python 3.6.6
[root@blog Python-3.6.6]# python3
Python 3.6.6 (default, Nov 8 2018, 07:40:48)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> dfdfdgffg^H^H^H^H
运行python3命令,在输错内容想删除时,按Backspace键发现出现的是‘^H’,
需要执行如下命令处理此问题:
yum install readline readline-devel -y
cd ~/upload/Python-3.6.6 #重新回到python3.6.6的解压目录文件
make & make install
- 此时python3.6.6已基本完成安装
4.2 安装虚拟环境
- 需要先安装pip
命令如下:
cd ~/upload
wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate #不检查证书
python get-pip.py
检查pip版本
[root@blog upload]# pip --version
pip 18.1 from /usr/lib/python2.7/site-packages/pip (python 2.7)
- 安装 virtualenv
pip install virtualenv
virtualenv的管理命令如下:
mkdir ~/projects/
cd ~/projects/
virtualenv myblog # 创建一个叫myblog的虚拟环境
cd myblog
source ./bin/activate #激活虚拟环境
deactivate # 停止虚拟环境
本次实验不直接用virtualenv管理虚拟环境,而是用它的扩展工具“virtualenvwrapper”
pip install virtualenvwrapper
mkdir ~/.virtualenvs
yum -y install vim # 安装vim编辑器
vim ~/.bashrc
查看virtualenvwrapper的安装路径
whereis virtualenvwrapper
显示如下:
virtualenvwrapper: /usr/bin/virtualenvwrapper.sh
编辑~/.bashrc文件,在末行添加虚拟环境目录的路径和virtualenvwrapper.sh的路径
export WORKON_HOME=~/.virtualenvs
source /usr/bin/virtualenvwrapper.sh
添加后,~/.bashrc文件的内容应该是下面这样的(有空行,未显示,不知什么原因)
# .bashrc
# User specific aliases and functions
alias rm=‘rm -i’
alias cp=‘cp -i’
alias mv=‘mv -i’# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fiexport WORKON_HOME=~/.virtualenvs
source /usr/bin/virtualenvwrapper.sh
接下来运行如下命令,使配置生效
source ~/.bashrc
virtualenvwrapper工具管理命令如下:
workon # 列出虚拟环境列表
lsvirtualenv # 同上
mkvirtualenv myblog # 新建一个名为myblog的虚拟环境
workon myblog # 切换到名为myblog的虚拟环境
deactivate # 离开虚拟环境
rmvirtualenv myblog # 删除名为myblog的虚拟环境
cpvirtualenv [sorce] [dest] # 复制虚拟环境
pip freeze > requirements.txt # 导出该环境下所有依赖到requirements.txt文件
4.3 安装nginx
yum -y install nginx
systemctl start nginx # 启动nginx
firewall-cmd --query-port=80/tcp # 查看防火墙80端口状态
firewall-cmd --zone=public --add-port=80/tcp --permanent # 永久开启80端口(重启系统不失效)
其他防火墙命令
firewall-cmd --remove-port=80/tcp --permanent # 关闭80端口
firewall-cmd --reload # 重新载入防火墙配置(关闭端口后需要重新载入配置才生效)
firewall-cmd --query-port=80/tcp # 查看防火墙80端口状态
用浏览器访问 VPS 的ip,页面如下则证明nginx安装成功
以下===之间带删除线的部分是用iptables防火墙替换系统自带的firewalld防火墙,经测试后端口一直不通,暂时舍弃此方法
================================================================================
安装iptables.services防火墙
systemctl disable firewalld.service #开机禁止启动centos7自带的防火墙服务
yum -y install iptables-services # 安装iptables-services
vim /etc/sysconfig/iptables~~
在/etc/sysconfig/iptables文件中添加
-A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
/etc/sysconfig/iptables文件最终结果如下:
# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
COMMIT
设置iptables.services
systemctl restart iptables.service # 重启iptables
systemctl enable iptables.service # 使iptables开机启动
重启linux系统使配置生效
================================================================================
4.4 安装mysql
yum -y install mysql
yum -y install mariadb-server mariadb
yum -y install mysql-devel
5、注册域名
-
访问 https://sg.godaddy.com/zh/ ,注册并登陆,既然是做学习测试用,找一个未被使用且价格不高的域名就行了,第一年14¥,第二年恢复原价(109¥左右)
搜索“wholovepython”的域名,如下图:
-
购买好域名后,点击自己的账户–访问我的账户–DNS
DNS设置成如下图的样子,A类型的值填写自己VPS的IP地址
在自己Win7系统上运行cmd命令,打开命令提示符窗口,ping一下自己的域名,例如:ping www.wholovepython.com
,能ping通则说明主机映射成功。
此时用浏览器访问自己的域名,同样显示nginx的欢迎界面。
6、创建项目
- 6.1 创建一个名为Blog的虚拟环境,并指定python的版本
mkvirtualenv Blog --python=python3
#此时会自动切换到虚拟环境,命令行前多了一个Blog标志代表在Blog的虚拟环境下,如:
# (Blog) [root@blog myblog]#
#以下操作都是在Blog虚拟环境下操作的
pip install django==1.10.6 #安装指定版本的django
django-admin startproject myblog . #注意此处末尾有个点‘.’
pip install uwsgi #安装uwsgi
systemctl start mariadb #启动mysql数据库
mysqladmin -u root password '123456' #修改mysql的root账户的登录密码为123123
mysql -u root -p #用此命令登录mysql,输入密码123456
create database myblog default charset=utf8;#创建一个新数据库myblog,并指定编码,以防博客有中文时显示乱码
#用exit命令退出mysql命令行
- 6.2 修改项目setting.py文件,把默认的数据库sqlite3改成mysql数据库
vim ~/.virtualenvs/Blog/myblog/settings.py
把
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
改成下面这样,注意每行末尾有英文逗号‘,’
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myblog', ## 数据库名称
'USER': 'root',
'PASSWORD': '123456', ## 安装 mysql 数据库时,输入的 root 用户的密码
'HOST': '127.0.0.1',
'PORT':'3306', #端口
'OPTIONS': {'charset': 'utf8'},#很重要,不然会乱码
另外,在setting.py文件的末尾处,把语言改成中文,把时区改成亚洲/上海,如下:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
修改静态文件路径,在setting.py文件末行添加
STATIC_URL = '/static/' #此行原文件有
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
修改
ALLOWED_HOSTS = []
为
ALLOWED_HOSTS = ['*']
然后运行
python manage.py collectstatic # 同步静态文件
- 6.3 验证服务是否正常
pip install mysqlclient #安装mysql客户端
python manage.py runserver #启动服务器
用secureCRT打开一个新的终端(不要关闭刚才那个正在运行python manage.py runserver的终端),运行如下命令:
yum -y install elinks #elinks可以访问网页
elinks --dump http://127.0.0.1:8000/ #运行此命令,显示“正常工作!”
- 6.4 刚才只是对django服务是否能正常运行做了一个简单的测试,接下来的任务量比较多,放到第7大步说明。
7、验证nginx + uwsgi + mysql + 域名访问
先熟悉下现在的环境,Centos7系统目前已经做了如下配置:
- nginx服务已安装,未修改配置文件,启动nginx服务,用浏览器能看到nginx的欢迎页面
- uwsgi已安装,未修改配置文件;
- mysql 服务已安装,并创建了myblog的数据库,而且django项目的默认数据库也改为了mysql
- 域名已经做了映射,域名:IP
- 防火墙firewall已经对外开放80端口
7.1 创建应用
- 创建app
workon Blog #切换到Blog的虚拟环境
cd /root/.virtualenvs/Blog/myblog #cd到项目的目录,即有manage.py文件的那个目录
python manage.py startapp blog #创建一个blog的app
- 把新app添加到setting.py文件的INSTALLED_APPS中
vim ~/.virtualenvs/Blog/myblog/settings.py
- 配置如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
- 迁移数据库
python manage.py makemigrations
python manage.py migrate
- 查看mysql:
mysql -u root -p
show databases;
use myblog;
show tables;
- 会发现myblog的数据库的数据表如下:
MariaDB [myblog]> show tables;
±---------------------------+
| Tables_in_myblog |
±---------------------------+
| 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 |
±---------------------------+
- exit退出数据库,修改nginx和uwsgi的配置
7.2 修改nginx和uwsgi的配置
以下操作一定要仔细
- 配置nginx
cd /root/.virtualenvs/Blog/myblog #切换到项目的目录
cp /etc/nginx/uwsgi_params ./ 把uwsgi_params文件复制到项目的目录下
vim /etc/nginx/nginx.conf
在/etc/nginx/nginx.conf
文件的http 块中添加“include /etc/nginx/sites-enabled/*;”
include /etc/nginx/conf.d/*.conf; #此行原文件中存在,有两个,http块中有两个这样的行,此处是上面的那个,并非是server{}中的那个
include /etc/nginx/sites-enabled/*;
把
user nginx
改为
user root # 此处用root不太好,后期再做优化,应该是和某些目录的权限设置有关
然后
mkdir /etc/nginx/sites-enabled #如果存在此目录就不用创建
ln -s /root/.virtualenvs/Blog/myblog/myblog_nginx.conf /etc/nginx/sites-enabled/
编辑myblog_nginx.conf
vim /root/.virtualenvs/Blog/myblog/myblog_nginx.conf
配置如下:
参考链接 https://www.jianshu.com/p/f83f8cca9a0a
server {
listen 80; # 监听哪个端口
server_name .vava.info ; # 此处是我的域名,也可以写公网ip地址
access_log /var/log/nginx/access.log main; # 日志记录
error_log /var/log/nginx/error.log; # nginx错误日志,可自行设置,但必须保证提前建立好该目录和文件
charset utf-8;
gzip on;
gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-
php application/json text/json image/jpeg image/gif image/png application/octet-stream;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# 指定项目路径uwsgi
location / {
include /root/.virtualenvs/Blog/myblog/uwsgi_params;
uwsgi_connect_timeout 30;
uwsgi_pass unix:/root/.virtualenvs/Blog/myblog/myblog.sock; # 这里需要改为你的目录
}
# 指定静态文件路径
location /static/ {
alias /root/.virtualenvs/Blog/myblog/static/; # 这里需要改为你的目录
index index.html index.htm;
}
}
- 配置uwsgi
vim myblog_uwsgi.ini
[uwsgi]
# 项目目录
chdir=/root/.virtualenvs/Blog/myblog/
# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 指定项目的application
module=myblog.wsgi:application
# 指定sock的文件路径
socket=/root/.virtualenvs/Blog/myblog/myblog.sock
# 启用主进程
master=true
# 进程个数
workers=5
pidfile=/root/.virtualenvs/Blog/myblog/uwsgi.pid
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=512
# 设置日志目录
daemonize=/root/.virtualenvs/Blog/myblog/uwsgi.log
# 配置文件内容结束
7.3 验证
- 重启nginx服务
cd /root/.virtualenvs/Blog/myblog
wordon Blog
systemctl restart nginx
uwsgi --ini myblog_uwsgi.ini
在本地系统打开浏览器,输入自己的域名,例如我的域名 www.vava.info
显示如下:
添加博客系统的超级用户:
python manage.py createsuperuser #输入账号和密码
用浏览器访问 www.vava.info/admin
截图如下:
8、总结
用了将近三天的时间,经历了各种排错,在VPS上恢复了好几次快照,目前已经基本实现Centos7 + python + Django + nginx + uwsgi + 域名访问个人博客系统,然而目前只有一个空壳子,在下一篇博客中更新博客的各项功能,最后列出各种文件的目录结构结束本篇博文:
说明:导出目录树的方法有点笨拙但是很实用,方法为在linux系统运行tar -czvf /root/.virtualenvs /root/virtualenvs.tar.gz
,把该目录打包下载到win7系统,用winRAR解压,然后在win7系统中把不需要显示的目录文件夹先手动删除,再运行cmd,cd到解压的目录,最后运行tree /F >D:\1.txt
,在D盘打开1.txt文件即可看到目录树,当然linux系统中也有tree命令,之所以没在linux系统中操作,主要是怕删错了文件
/root/
└─.virtualenvs
│ get_env_details
│ initialize
│ postactivate
│ postdeactivate
│ postmkproject
│ postmkvirtualenv
│ postrmvirtualenv
│ preactivate
│ predeactivate
│ premkproject
│ premkvirtualenv
│ prermvirtualenv
│
└─Blog
│ lib64
│
├─bin
├─include
├─lib
└─myblog
│ manage.py
│ myblog_nginx.conf
│ myblog_uwsgi.ini
│ uwsgi.log
│ uwsgi.pid
│ uwsgi_params
│
├─blog
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tests.py
│ │ views.py
│ │ __init__.py
│ │
│ ├─migrations
│ └─__pycache__
├─myblog
│ │ settings.py
│ │ urls.py
│ │ wsgi.py
│ │ __init__.py
│ │
│ └─__pycache__
└─static
└─admin