Move WordPress sites to a new domain

Today I finally decided to move this site from its old domain to this new one, chunliu.me, which I got last year. For a personal hosted WordPress site, changing domain name is not a straight forward task, especially when you don’t want to break the existing external links that point to the site. Here is how I did it, with a lot of search on internet of course.

Copy the database and WordPress folder

To minimize the impact to the existing site, I duplicated the MySQL database of this site and its WordPress folder. Copy WordPress folder is easy, simply use cp command to copy the whole folder. Copy database is a bit tricky because I forgot the password of the MySQL root user. I used the following way to reset the password of the root user.

  1. Run mysql with --skip-grant-tables.
    $ sudo service mysql stop
    $ sudo mkdir -p /var/run/mysqld
    $ sudo chown mysql:mysql /var/run/mysqld
    $ sudo mysqld --skip-grant-tables --skip-networking &
    $ jobs
    
  2. Update the password of root user with mysql client.
    $ mysql -u root
    mysql> FLUSH PRIVILEGES;
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
    mysql> QUIT;
    
  3. Restart mysql service.
    $ sudo pkill mysqld
    $ jobs
    $ sudo service mysql start
    

With the above steps, the database can be copied with the following command.

mysqldump -u root --password=<pwd> <original db> | mysql -u root -p <new db>

Update the URL of the new site

With the copied WordPress and database, the URL needs to be updated in the following several places.

  • wp_config.php: update DB_NAME and DOMAIN_CURRENT_SITE;
  • wp_options table: update site_url and home;
  • wp_site and wp_blogs table: update domain;

Create a URL rewrite rule in the old site

The last thing is to create a url rewrite rule in the old site so that all requests to the old site can be redirected to the new site. This will help to keep the external links without broken.

Edit the .htaccess file of the old site with the following code.

RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [OR]
RewriteCond %{HTTP_HOST} ^blog\.olddomain\.com$
RewriteRule (.*)$ https://newdomain/$1 [R=301,L]

With that, the site is moved to the new domain successfully.

迁移到LAMP

虽然Blog现在不流行了,这个Blog我也不常更新,不过还是趁着新加坡国庆假期,把整个Blog迁移到了一个新的,基于Windows Azure IaaS的LAMP虚拟机上。这么做,一来是体验一下Azure虚拟机对开源系统的支持到底如何,二来也是解决系统稳定性和升级的问题,毕竟WordPress还是在原生的LAMP系统上更好一些。

之前用Azure的PaaS来构建WordPress系统,遇到的主要问题,就是系统升级。因为PaaS的特性,要升级WordPress的版本,需要重新部署应用。即使是安装个插件和主题之类的小部件,也需要把相应的部件部署到安装包里。这样不但麻烦,而且WordPress的在线升级和部件安装的功能完全无法使用。现在将它搬到LAMP上,这些问题都迎刃而解了。

初步体验,Windows Azure对开源系统的支持挺不错的。我从Gallery里直接选的Ubuntu Server 13.04,然后apt-get安装APH,配置apache,MySql和WordPress,一切顺利,顺带还把以前在DigiCert申请的SSL证书也用上了,目前看来一切正常。剩下的一个小问题是媒体文件的管理。我倾向于使用公开的媒体文件服务,比如flickr和YouTube,而不是把文件存储在WordPress里。不过,使用那些服务,上传和写文章就变得比较麻烦,不知道有没有好的编辑器插件可以解决这个上传的问题。或者试一下Windows Azure Storage for WordPress也说不定。

Blog修复记

本来以为blog放在Azure上可以一劳永逸,再也不会宕机了,谁知上周我在印度的时候,blog忽然出HTTP 500的错误,访问不了了。Azure在每个月底的时候,会重启服务器,重启的过程会重新部署package。我感觉可能是重新部署package时出错了。

我用remote desktop连接到一台Azure Server上,查看了startup tasks log。其中有一个错误,是在安装SQL Driver for PHP的时候出错了,这个driver的安装包无法从原来的地址下载。我试着用浏览器打开那个下载地址:http://download.microsoft.com/download/C/D/B/CDB0A3BB-600E-42ED-8D5E-E4630C905371/wpi_sqlsrv301_php53.EXE,果然不可用了。搜索了一下,原来随着WPI 4.0的发布,这个安装包的地址变了,新的地址是:http://download.microsoft.com/download/C/D/B/CDB0A3BB-600E-42ED-8D5E-E4630C905371/wpi40_sqlsrv301_php53.EXE。IIS的论坛里有完整的讨论:http://forums.iis.net/p/1189248/2031677.aspx

我update了一下部署Azure服务的package,现在blog终于回来了。更改package的步骤如下:

  1. 删除resources目录下原有的WebPICmdLine目录,这个是旧的WebPI预览版的命令行程序。
  2. 新建一个WebPICmd目录,将新的WebPICmd.exe复制到这个目录下,Microsoft.Web.PlatformInstaller.dll也需要复制过来。它们的默认安装路径是”C:Program FilesMicrosoftWeb Platform Installer”。
  3. 更新bin目录下的install-php-impl.cmd,将原来的命令行:

    “..resourcesWebPICmdLinewebpicmdline” /Products:PHP53,SQLDriverPHP53IIS,

    改成:

    “..resourcesWebPICmdwebpicmd” /Install /Products:PHP53,SQLDriverPHP53IIS,

    其它的保持不变。

  4. 重新package,然后选择更新已部署的服务。
  5. Package重新部署后,可能还需要reimage azure服务器。

希望这种更新程序后改变URL的情况不会频繁发生。

升级Windows Azure中的应用

昨天blog页面打开突然变成空的了,post无法显示,但是tags和comments列表是正常的。这说明不是数据库连接的问题。我连上Windows Azure的管理页面看了一下,两台WebRole的机器昨天被重启了。Windows Azure的机器重启之后,系统会被重置,应用会重新部署。我在前面的post里说过,WordPress for SQL的plug-in有一个bug,以前我是通过手工上传更新后的文件解决的,并没有更新安装包。应用重新部署后,就的文件又回来了,bug就又出现了。

为了一劳永逸,我昨天重新做了安装包,用升级的方式更新了应用的部署。Windows Azure支持增量更新和完全更新,我用的是增量更新的方式,因为我只需要更新一点点代码。步骤如下:

  1. 在Windows Azure管理界面,选择对WebRole升级,上传新的安装包和配置文件。因为我不需要升级配置,因此我将Azure中已有的配置拷贝了一份,作为新的配置文件。这能保证新配置和原配置一摸一样。
  2. 选择升级之后,两个node会被先后升级。升级完成后,可能会出现HTTP 500。我想主要是因为应用被重新部署了,但是机器没有重启,状态有混淆。
  3. 分别重启两个node之后,一切就恢复正常了。

完全更新的方式稍有不同,它需要新建一个staging部署,将新的安装包和配置文件部署在staging中,测试完成之后切换production和staging。这种方式适合有重大代码和配置更新的情况。

现在,似乎通过页面来发布新post会有问题,而用Windows Live Writer就没问题,我也就懒得管页面发布到底是什么问题了。Windows Live这个品牌不会继续了,Live Writer怎么办呢?

Now, Powered by Windows Azure

azure

早在年初的TechReady上,就看过Scott Guthrie演示在Windows Azure上跑WordPress。当时我正因为这个blog的主机商时不时掉线而伤脑筋,看了他的演示就想,不如将这个blog搬到Windows Azure上来。可是事情一直很多,直拖到现在。

Windows Azure的服务我在一两年前测试过,当时还只支持.NET。现在已经可以支持PHP,node.js,Java等等非微软系的技术了。对于在Windows Azure上部署WordPress,其实也很简单,下面这篇文档就包含了所有必要的信息:

How to deploy WordPress Multisite to Windows Azure using the WordPress scaffold

实际部署时,还是有些小细节需要注意:

  1. 这篇文档里的.phar下载的WordPress 3.2.1,不是最新的版本。可以将Scaffold原名从github上下载下来,修改相应的下载链接,来下载最新版的WordPress。
  2. 在Azure上部署的PHP程序,程序目录里的文件不是永久有效的。当Azure的虚机重启之后,会重新部署整个package。所以,在WordPress里下载theme和plugin不可行,需要先将需要的theme和plugin下载到项目的对应文件夹里,package在一起部署。
  3. 1.1.4版的数据库抽象库有一个小bug,在wp-contentmu-pluginswp-db-abstractiontranslationssqlsrvtranslations.php的第726行,正确代码是:$pattern = ”/LIMITs*(d+)((s*,?s*)(d+)*);{0,1}$/is”;
  4. 我在部署时遇到一个E:SiteRoot目录的写入问题。在倒入post或者在线安装plugin时,WordPress需要向这个目录写入临时文件,如果这个目录无法写入,则这些操作都无法做了。具体的原因我没找到,最终我是通过RDP到WebRole,手工修改目录权限解决的。这些权限会在下次VM重启之后被还原,还好我不是经常需要向这个目录写入文件。
  5. 另外,RDP的配置,可以参考这篇文章