博客迁移历程

之前我的博客托管在外网的Linode上,Linode整体还是挺好的,支持一键迁移,服务器也很稳定,网站上教程资源很丰富;缺点就是国内访问的网速总是不理想,延迟很大,其间我尝试了 Linode 不同地区的机房,问题都没有解决,网速不稳定,经常会很慢。

近期,我下定决心迁移博客,彻底解决这个问题,后续也准备将博客继续维护起来;经过广泛调研,并综合考量性价比等多方面因素,决定将博客迁移到阿里云。接下来,我将详细分享博客迁移的全过程,其中我也踩了不少坑,希望能给大家提供一些参考。

博客运行环境

博客的运行环境主要涉及以下技术栈:

  • 操作系统:Ubuntu 16.04
  • 编程语言及框架:Ruby 2.3.8、Rails 4.2.4
  • 数据库:MySQL 5.7
  • 搜索服务:Solr 5.5.4
  • Web 服务器及应用服务器:Nginx + Passenger

此外,Rails依赖的需要本地编译的包如下:

  • nokogiri 1.6.6.2
  • mysql2 0.3.20

部署工具方面

  • ansible 2.0.0.2
  • bundler 1.17.2
  • capistrano 3.6.1

迁移目标及方案

如果是将上述系统直接部署到Ubuntu16.04上会很简单,因为我前期已经整理了功能完善的ansible部署工具,可以实现一键部署,完成所有的依赖安装和环境配置。但考虑到Ubuntu16.04已停止维护,为了让这次迁移更加彻底,我决定将操作系统升级到最新的Ubuntu24.04。

不得不说,我前期严重低估了迁移的难度,从过年到现在,竟然花了将近两周时间(原本预计只需两天)。

方案一、 折腾本地虚拟机,重新启用ansible部署工具(失败)

  • 安装Mac版Ubuntu  24.04 虚拟机:需要装arm版的【解决】。难点:arm版本导致很多依赖包无法使用或默认缺失,需要单独下载和编译。
  • 使用最新版ansible软件(2.18.2):仅因为不想安装太久的版本【艰难解决】。难点:和老版本不兼容,部分需要修改代码解决。
  • ~~原计划安装最新版的Ruby 4.1 ,之后因为很多依赖包不兼容,放弃。~~
  • 安装Ruby-2.3.8版本【解决】。难点:缺少libssl1.0-dev,需要源码编译安装,然后才能编译安装Ruby,建议使用rvm来安装。
  • 安装bundler包:使用1.17.2版本。
  • 安装依赖gem包 - nokogiri【艰难成功】。nokogiri编译安装依赖部分本地包,需要通过源码编译安装iconv、 libxml2-2.9.2、libxslt-1.1.28等。
  • 安装依赖gem包 - mysql2:其编译依赖mysql5.7的dev包
  • 安装Mysql 8.0 ,与mysql2 0.3.20包冲突,但这个是底层包无法更新。【冲突】
  • 安装mysql 5.7 成功,但安装依赖的dev包,和其他dev包冲突。【冲突】

在解决了无数问题后,发现这条路走下去,即使编译通过并安装成功,运行过程中也难免出现各种问题,于是决定放弃方案一。

方案二、使用docker镜像安装

为了避免上面遇到的各种编译及依赖问题,我决定将博客主体继续运行在Ubuntu16.04上,但又不想放弃升级到Ubuntu24.04的想法。经过综合考虑,决定采用Docker来部署,这样外部的主机使用Ubuntu24.04,后续有时间再对博客做全面升级,以支持最新的操作系统。具体步骤如下:

  1. 本地安装Ubuntu镜像
    • 开发环境:采用 arm 架构安装 Ubuntu 16.04 镜像,用于博客工程的开发测试和更新,目前使用过程中未发现问题。
    • 准生产环境:为了与生产服务器架构保持一致,采用amd64架构安装Ubuntu镜像。
    • 模拟生产宿主环境:本地安装Ubuntu24.04镜像,用于模拟生产环境的宿主服务器。
  2. 初始化镜像环境:安装必要的包、创建用户、配置ssh服务器。
  3. 安装应用程序:在镜像中安装Rails、solr等应用程序,可以使用之前做的ansible工具直接安装。
  4. 保存镜像:将安装好的容器保存为镜像,使用commit命令。
    • 镜像可以认为是稳定的、可复用、持久化的系统。
    • 容器可以认为是可以丢弃的、不稳定的存在,可以很方便用来试错。
    • commit前尽量删除无用的文件、安装程序等,减小镜像的体积。
  5. Docker向宿主机器暴露端口,进行端口映射:
    • 开发环境:为方便开发,开放了多个端口(前面为宿主机端口、后面为镜像中开放的端口):
      • 10022:22 :SSH服务,便于上传和编辑文件。可通过SSH支持VSCode远程开发代码,但无法使用 AI 是个小缺点,后续可考虑通过 SSH 同步工具实现代码同步。
      • 10080:80 :HTTP服务
      • 13000:3000:Rails server端口,便于在宿主机进行调试
      • 13306:3306:MySQL数据库端口,便于通过Mac的图形化界面进行管理
      • 18983:8983:Solr搜索端口,便于在宿主机调试
      • 8086:8086 和 8087:8087 :作为备用端口,避免每次开放新端口都需要 commit 镜像的麻烦。
    • 生产环境:出于安全性考虑,仅开放最少的端口:
      • 33000:3000:Passenger服务器的默认端口
      • 30022:22 :SSH服务器的端口,为保障安全,关闭了密码登录,仅允许证书登录,并安装了 Fail2ban 软件。
  6. 数据库配置:出于性能考虑,使用宿主机的MySQL服务器。避免在Docker容器中直接运行MySQL。
    • 为了安全,通过设置ufw防火墙,仅允许容器固定IP远程访问MySQL。
  7. 防火墙配置:配置docker-ufw,防止外网访问docker暴露的端口。安装完正常无需特殊配置。
  8. 镜像迁移:将生产镜像导出,上传到生产环境,再导入到生产服务器。

至此,博客主体部署已完成,下面简单列举一下生产服务器的其他配置内容,供大家参考:

  1. SSH登录配置
    • 禁止以root身份登录
    • 取消使用密码登录,改用SSH证书登录
  2. 设置虚拟内存,参考:Ubuntu实例中添加swap分区的方法
  3. 设置ufw防火墙
  4. 安装Fail2ban软件
  5. Web 服务器配置:配置nginx,安装https证书。

参考教程

  1. Ubuntu使用certbot配置nginx服务器的ssl证书
  2. Deploying a Ruby app on a Linux/Unix production server
  3. Installing Older Ruby Versions on Ubuntu 24.04 and 22.04
  4. How to install MySQL 5.7 on ubuntu 20.04 or later
  5. Ubuntu实例中添加swap分区的方法
  6. UFW-Docker 使用教程

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《ITechLib》

Ubuntu 16.04虚拟机安装小记

虚拟机的下载安装在此就不谈了,在安装完成后建议安装“虚拟机工具包”,以便可以方便地在宿主主机和虚拟间进行复制粘贴,共享文件、自由调节分辨率等操作。下面主要记录一下我安装虚拟后做的一些常见设置。

1. 将个人用户文件夹变为英文

因为我一般喜欢在终端中进行操作,这时文件夹是中文很难切换。具体操作方法如下:

  1. 打开终端,先修改为英文环境:export LANG=en_US
  2. 更新文件夹为英文:xdg-user-dirs-gtk-update,会弹出对话框,选择确认
  3. 恢复中文环境: export LANG=zh_CN

重启后会有提示文件夹与当前语种不一致,此时选择不变更即可。

2. 禁止Super快捷键

默认按下Super键时会弹出Dash页面(注: 左上角的图标),整个屏幕都会被占据,体验很差。禁止方法如下:

  1. 在“Ubuntu 软件”中搜索compizconfig-settings-manager,然后下载安装
  2. 输入快捷键Alt+F2,进入“显示运行命令提示符”;输入about:config并回车确认,打开Unity configuration
  3. Launcher选项卡中将Super快捷键禁止即可

3. 安装oh-my-zsh

使你的终端从此不一样,用过的人都知道,哈哈。

  1. 安装zsh:sudo apt-get install zsh
  2. 安装oh-my-zsh

    sh -c “$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)”

  3. chsh -s `which zsh`
  4. 重启虚拟机

更详细的安装方法见:在Ubuntu上安装zsh

4. 安装其他命令行工具

见我另一个文章常用软件推荐

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《ITechLib》

非root用户启动apache、mysql

近期在组内搭建了一个wiki平台,方便知识整理分享。但由于没有自己控制的服务器,只能使用一台公共的服务器。root用户需要申请才能使用,网上很多教程都是针对root用户的,包括安装启动。其实apache、mysql从设计之初就是支持非root用户使用的,用户可以根据自己需要指定端口、数据存放地址以及其他一些配置信息。下面简单介绍一下非root用户启动需要做哪些事情(安装为了简单跟管理员申请了一下root权限)

1.启动apache1

可以使用指定的httpd.conf文件来启动apache,命令如下:

/usr/local/apache2/bin/apachectl -f /your/path/httpd.conf   -k start

1.1 修改端口

直接执行上面命令可能会报错,因为apache默认绑定端口位80,而非root用户是不允许使用1024以下的端口的,可以在httpd.conf中修改。

Listen 80 #修改为--> Listen 9001

如果改后端口外部不可访问可以试试8080等常用端口,或者跟管理员申请开发新配置的端口。

1.2 修改用户组

在httpd.conf中找到User/Group

User _www
Group _www

修改为你自己的组,如下所示:

User flyingbird
Group flyingbird

1.3 修改html的根目录

有两个地方要改,分别如下:(DocumentRoot,Directory)

DocumentRoot "/Library/WebServer/Documents"
<Directory "/Library/WebServer/Documents">

上面两个地址改为你要放网站的地址,两者要保持一致。

1.4 加载必须的mod

可以直接在httpd.conf中找下看,常用的mod一般都有,只要把注释去掉即可。

1.5 修改PidFile和日志路径

可以直接在httpd.conf中修改,包括PidFile、ErrorLog、ServerRoot等,如果不必要尽量不要修改。

1.6 停止apache

/usr/local/apache2/bin/apachectl -f /your/path/httpd.conf -k stop

2. 启动mysql2

mysql比较特殊,也可以支持非root安装启动(一般用户),但更通用的做法是使用mysql用户启动。

2.1 安装启动

在通过yum安装好后,yum install mysql mysql-server,可以登录mysql用户,如果没有的话可以先建一个:

# adduser mysql
# passwd mysql 设置密码

然后登录mysql用户并启动

/etc/init.d/mysqld start

停止:

/etc/init.d/mysqld stop

默认是采用/etc/my.cnf文件配置的,可以根据需要修改其中的配置

2.2 修改root用户密码

$ mysql -u root

mysql> SET PASSWORD FOR ''@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR ''@'host_name' = PASSWORD('newpwd'); 

参考资料:

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《ITechLib》