在Ubuntu 15.10下配置LEMP环境(Linux + Nginx + MySQL+ PHP7.0)

0 准备工作

这里假设已经新建了一个VPS并能够通过SSH连接上服务器。系统方面我采用了Ubuntu 15.10

首先安装一些常用的工具,我习惯用 VIM,所以还顺便加载了常用的一套 VIM 配置文件。当然只是用来配置网站的运行环境的话nano就足够了。

aptitude install git vim python-pip
git clone git://github.com/amix/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_basic_vimrc.sh

1 基本的系统设置

设定主机名称(hostname)

$ hostnamectl set-hostname hostname

把上条命令中的hostname 替换为主机名字

1.1 更新hosts

更改/etc/hosts

127.0.0.1   localhost.localdomain localhost
12.34.56.78 hostname

这里的hostname 需要改成前面设定的对应值。

1.2 设定时区

dpkg-reconfigure tzdata

设定完成后可以输入date 命令再次确认是否设置成功。

1.3 配置自动更新(unattended-upgrades)

一般情况下系统已经配置了自动更新,可以配置为定期升级所有软件包或是仅升级安全相关的内容,如果不确定是否已经存在于系统,可以尝试安装一下:

apt-get install unattended-upgrades

关于自动更新的详细内容,请参考:https://help.ubuntu.com/lts/serverguide/automatic-updates.html

2 新增用户

到目前为止都还是用root账号在进行操作,这是不安全的习惯。比较推荐的的系统管理方式是通过非 root 账号进行管理并设置禁止使用密码登陆 root 账号(可以配置为证书登陆)。

$ adduser example_user
$ adduser example_user sudo

3 配置防火墙(ufw)

Linux的内核包括了一个叫netfilter的子系统用来管理进行服务器的网络流量,但是它非常底层,没有用户界面,所以就有了经常听见的iptables。iptables可以认为是对netfilter的一个包装。

但是通过iptables配置过服务器的防火墙比较繁琐,所以又有了ufw。ufw可以比较方便地生成iptables的规则,可以认为是对iptables的进一步包装。关于ufw的进一步信息,可以到这里查看:https://help.ubuntu.com/community/UFW

默认情况下,Ubuntu中的ufw默认是关闭的,可以通过以下命令查看ufw的状态:(接下来默认已经不再直接用root账户登陆,所以命令前会加上sudo)

sudo ufw status verbose

在制定具体的防火墙规则前,先设定好默认的防火墙规则:

sudo ufw default deny incoming
sudo ufw default allow outgoing

以上两条命令的意思从字面上就可以理解——拒绝所有进站的流量,允许所有出站的流量。如果之前有过用iptables配置防火墙的经验就不难发现ufw的方便之处——不用输入包括IP地址在内的难以理解的规则条目,只要通过简单易懂的英文单词就可以操作防火墙(当然也可以使用IP和端口的组合,只不过还是比iptables来得方便)。另外需要讲一下的是:默认情况下ufw会允许ping(ICMP)请求

接下来可以制定一些常用的防火墙规则了。如果只是用来做小型网站的服务器,其实只要开放ssh和Web(80)端口即可(FTP不是很必要,通过SFTP传输文件即可),如果有计划上SSL证书,HTTPS需要的端口也可以开放。在ufw的命令中可以直接使用端口号和IP地址,不过一些常见的任务也可以直接输入英文单词(这才是用ufw的意义所在):

sudo ufw allow ssh
sudo ufw allow www
sudo ufw allow https

到目前为止ufw设定的防火墙规则还没有生效,因为ufw默认是被关闭的,所以还需要将它启用使前面输入的规则生效:

sudo ufw enable

4 配置WEB服务器

这里配置的WEB服务器环境是LEMP,其中PHP采用7.0版本。

目前为止(2016.3.4),Ubuntu默认的软件仓库中还没有包含7.0版本的PHP,如果要体验PHP7.0一般来说需要自己编译。不过也有相对省事的办法,那就是通过PPA安装。PPA是Personal Package Archive的缩写,顾名思义,是由个人分发的软件包,理论上安全性是有一定问题的。不过这里用到的这个PPA目前来说是被广泛使用和认可的,如果只是用来做个人网站的服务器用不用太过担心。

4.1 添加需要的PPA

以下的命令会将安装PHP7.0所需的PHP添加到系统中然后顺便升级一下系统内的软件包:

sudo apt-get install software-properties-common python-software-properties
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update && sudo apt-get upgrade

因为这个PPA作者的名字中含有一些特殊字符,如果系统的字符集不是UTF-8的话可能会遇到一点问题,解决方案很简单,详见:https://github.com/oerdnj/deb.sury.org/issues/56

另外该PPA的官方网页是:https://launchpad.net/~ondrej/+archive/ubuntu/php

4.2 安装PHP7.0

运行以下命令安装php7.0:

sudo apt-get install -y php7.0 php7.0-fpm

这个PPA只包括了Ubuntu 14.04, 15.10, 16.04三个版本的Package,所以如果你安装的不是这三个版本之一,会遇到找不到软件包的提示。

4.3 安装Nginx和MySQL

sudo aptitude install nginx
sudo aptitude install mysql-server

安装过程中会需要你输入MySQL的管理员账号和密码,按提示操作即可。

4.4 安装常用的PHP模块

sudo aptitude install php7.0-mysql php7.0-curl php7.0-json php7.0-gd php7.0-mcrypt php7.0-opcache php7.0-xmlrpc php7.0-intl php7.0-xml

4.5 进行必要的配置

/etc/php/7.0/fpm/php.ini中将选项cgi.fix_pathinfo的值更改为0:

cgi.fix_pathinfo=0

/etc/php/7.0/fpm/pool.d/www.conf中将修改以下两行:

; listen = /run/php/php7.0-fpm.sock
listen = 127.0.0.1:9000

修改PHP上传文件大小限制:

/etc/php/7.0/fpm/php.ini中修改如下两项设置(把100M改成对应的数字):

upload_max_filesize = 100M
post_max_size = 100M

在Nginx的配置文件/etc/nginx/nginx.conf中,修改(或增加)以下一行:

client_max_body_size 100m;

重启PHP-FPM和Nginx服务让配置生效:

sudo service nginx restart
sudo service php7.0-fpm restart

到这里为止,网站的运行环境基本搭建完成。在这个基础上,如果需要搭建WordPress之类的程序只要在Nginx中设置好对应的虚拟主机即可。如果不希望通过MySQL命令行来直接操作数据库,可以安装phpMyAdmin。

另附:WordPress推荐的Nginx设置:https://codex.wordpress.org/Nginx

[WordPress 主题] Goule 文档 | Documentation for Goule

这里是 WordPress 主题 Goule 的官方页面,目前的最新版本是 1.0.3,下载地址:GitHub

主题介绍

Goule 是一个基于 Bootstrap 开发的单栏响应式 WordPress 主题,界面简单干净,可以同时兼容手机和电脑屏幕,定位是小型个人博客主题。目前已提交到官方的主题目录,尚在审核中,暂时可以在 GitHub 下载试用。

Goule是一个免费的主题,你可以随意使用它。

界面截图

Goule 1.0.2 screenshot

下载地址

安装使用

  1. 下载包含主题文件的压缩包(下载地址见上一节)
  2. 将压缩包的内容解压并上传到WordPress根目录下的wp-content/themes/ 文件夹下
  3. 将解压或上传后的主题目录名称更改为goule
  4. 在WordPress后台激活使用

使用说明

  1. 主题可以自定义导航菜单(位于博客名称之下),可以到后台导航 -> 菜单 进行相关设置
  2. 导航菜单使用了wp-bootstrap-navwalker,提供了一些额外功能。例如:在导航菜单项中插入 Glyphicons 图标。具体可以参考 wp-bootstrap-navwalker的说明。可用的 Glyphicons 可以在 Bootstrap 的网站上找到
  3. 网站的档案页面可以同时显示TAG、分类、日期、附件的列表,如果需要使用可以新建一个页面,选择使用档案(Archives) 模板即可
  4. 主题的定位是小型博客,注册登陆这样的功能不是特别需要(小型博客很少有固定用户),所以登陆和登出链接设置在页面最下方,比较隐蔽(考虑到一般只有管理员会用到)
  5. 管理员登陆后如果需要直接在文章页面跳转到编辑页面,点击顶部 Admin bar 上的编辑文章即可(多数主题在登陆后会有文章旁边放置一个“编辑”按钮),如果你禁用了 Admin bar,可能会有点不方便

Here is the official website of Goule, a WordPress theme developed by me, its lastest version is 1.0.3.

The latest version can be found at GitHub(click to download page) .

Introduction

Goule is a free responsive single-column WordPress theme with Bootstrap bundled. It's simple, clean and compatible with mobile devices and desktop screens. Goule was designed for small blogs.

I have submitted Goule to WordPress official theme repository, but is still under reviewing. You may download a zip package on GitHub for a try.

Screenshot

Goule 1.0.2 screenshot

Download

Installation

  1. Download the zip package(See Dowload section above)
  2. Follow the official guidance for add a new theme

How to Use

  1. To configure the navigation menu(located under the blog title), go to Appearance > Menus
  2. The navigation menus makes use of wp-bootstrap-navwalker for some wonderful functions. For example: adding Glyphicons icon bundled in Bootstrap to a menu item. More detail can be found here. Available Glyphicons can be found here. A readme.txt, located at directory root of this theme, also contains details about how to use this
  3. An useful archive page template is delivered with Goule, which is capable of listing TAGs, categoies, date archives, attachment archives on a single page. To use this, create a new page and choose the template Archives
  4. This theme is aimed for small blog using, that is why login/logout button is put at bottoms of pages rendered with small-sized text. Also for the same reason, no Edit button will be found at post/page even if you are logged in as an administrator, because users are expected to use Edit Page/Edit Post link on the Admin bar which will be shown after logged in. I know this will cause some inconvenience to those who have disabled the Admin bar. I'm sorry for that. :(

将QQ同步助手导出的通讯录导入iCloud的方法

QQ同步助手导出的vCard格式的通讯录直接导入网页版的iCloud会出错

解决方案如下:

  • 从QQ同步助手导出vCard格式的通讯录
  • 导入GMAIL的通讯录
  • 在GMAIL中合并重复联系人
  • 从GMAIL中导出vCard格式的通讯录
  • 导入iCloud

对Queryset进行查找、过滤时使用动态的字段名

对Queryset进行查找和过滤是Django中最常见的操作之一,不过一般情况下是对已经确定的字段进行查找或是过滤,例如:

Entry.objects.get(id=123)
# 或是更复杂一点,用到lookup type
Entry.objects.get(headline__contains='Lennon')
在这样的查询中,idheadline都是已经确定的字段。

如果想要动态地指字被查询的字段,可以像这样做:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}
Person.objects.filter(**kwargs)
“这在Python中是非常普通和常用的技巧。”1

Python中被引入模块(module)中属性(attribute)和全局变量的命名空间问题

在之前的一篇博客「Django(Python)中按屏幕显示宽度截取字符串」中,我写了一个用来获取字符串在屏幕上显示宽度的函数get_screen_width(*args, **kwargs),这个函数放在一个utility.py文件中,在项目的其它文件中要使用这个函数时,可以通过这样的方式来使用它:

import utility
screen_width = utility.get_screen_width(input_str)
这是Python中很常见的场景,但是使用这个函数的时候我还是产生了一些困惑。

get_screen_width这个函数使用了一个定义在utility.py中的全局变量WIDTHS,问题就在于:

当我在其它文件中引入get_screen_width()并调用时,函数对WIDTHS这个全局变量的使用能否正常工作?

当时我简单地测试一下后没问题就没有多想。今天在翻看Python文档的时候看到一段话:

Strictly speaking, references to names in modules are attribute references: in the expression modname.funcname, modname is a module object and funcname is an attribute of it. In this case there happens to be a straightforward mapping between the module’s attributes and the global names defined in the module: they share the same namespace!

...

It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called.1


这里明确说了两点:

  • module.funcname和module中的全局变量共享同一个命名空间
  • 对定义在模块中的函数来说,“全局空间”指的是其所在模块的命名空间,不管从哪里或者什么别名来调用这个函数
——这两点似乎就是对上面这个疑问的明确回答,不知道想的对不对。