TRANSFER/MIGRATE SERVER -- 迁移服务器

到2019年9月1日,本网站[凹大卜]上线累计一整年,访问量约7万次。感谢热心网友积极提出问题和参与讨论,使凹大卜更加完善丰富!

由于凹大卜用了亚马逊AWS EC2的一年免费服务器,9月1日就会到期。之后接着用,每个月就会收费了。博主囊中羞涩,既然亚马逊还有这活动,不然就再来一次? 只用换一个邮箱[注册]AWS就可以再获得一年的服务器使用权了。过程中仍需要信用卡信息,用和之前一样的卡也没关系。

选择服务器系统时,没注意,一不小心选了AWS默认的Amazon Linux 2操作系统。虽说和Ubuntu同属Linux系统,但操作会略有不同。推荐仍然使用Ubuntu系统!使用Ubuntu系统的可以参考之前[部署服务器教程]

旧服务器数据库备份

备份数据库的命令比较简单,选择旧服务器中awesome数据库进行备份导出backup.sql文件:

$ mysqldump --user=username --password=password --opt awesome > backup.sql

下载backup.sql到本地,以备恢复到新服务器使用。数据库备份与恢复的详细教程请参考:[数据库备份与恢复]

新实例配置

启动实例(instance)之后我们首先要设置几项内容:

  • 启动时会提示下载公共秘钥。秘钥是一个.pem文件,下载到本地电脑。这个秘钥可以用于以后网站主连接服务器是的身份验证。

  • 设置SecurityGroup, 在Inbound选项卡中添加HTTP, HTTPS,和SSH, 如下图所示:SecurityGroup。添加HTTP和HTTPS是为了以后访客可以从80和433端口访问到网站服务器。SSH端口则是为了网站主与服务器进行远程命令行操控或传输。

  • 申请静态ip地址(Elastic IPs), 在页面左边的菜单中选择Elastic IPs, 并 Allocate new address, 选项中勾选关联现有的服务器实例(instance)。
远程服务器配置

为了从本地连接服务器博主使用了SecureCRT来进行SSH的链接,配置时需要填写服务器的Hostname, Username, 并选择之前现在的.pem文件作为PublicKey进行连接。配置如图所示: SecureCRT

一旦连接上就可以对服务器进行远程操作了,过程跟[部署服务器教程]中的类似。不同的是,在Amazon Linux 2中没有apt或apt-get, 而需要用yum来安装需要的Packages.

安装之前需要先安装Epel的资源库:

$ sudo yum install epel-release

然后安装python3, nginx, lrzsz:

$ sudo yum install python3 nginx lrzsz

安装mysql server比较麻烦,博主安装的是mysql 8.0版本的:

$ wget https://repo.mysql.com/mysql80-community-release-el7-1.noarch.rpm
$ sudo yum localinstall mysql80-community-release-el7-1.noarch.rpm
$ sudo yum install mysql-community-server

安装好后我们启动MySQL Server:

$ service mysqld start

查看并复制临时密码:

$ grep 'temporary password' /var/log/mysqld.log

更改密码:

$ mysql_secure_installation

设置完成后就可以随时连接MySQL Server了:

$ mysql -u root -p

然后可以用之前教程中的schema.sql初始化数据库(需要用sudo rz命令将schema.sql传到服务器):

$ mysql -u root -p < schema.sql

然后将之前从旧服务器中备份的数据库backup.sql传送到服务器并恢复到新的服务器数据库中:

$ mysqldump --user=root --password=password awesome < backup.sql

数据库布置好后,我们来安装python所需要的一些Packages:

$ sudo pip3 install supervisor jinja2 aiomysql aiohttp markdown

在服务器上创先目录/srv/awesome/以及子目录:

/
+- srv/
   +- awesome/       <-- Web App根目录
      +- www/        <-- 存放Python源码
      |  +- static/  <-- 存放静态资源文件
      +- log/        <-- 存放log
部署本地到服务器

部署本地文件到服务器博主仍然使用Fabric。fabric 有了2.0版本,但之前的脚本无法运行。我们来安装1.x的fabric:

$ sudo pip install 'fabric<2.0'

改写之前的部署脚本fabfile.py,主要修改env.hosts, env.key_filename, db_password, chown的用户和组。然后重启supervisor和nginx的命令也要改:

import os, re
from datetime import datetime

# 导入Fabric API:
from fabric.api import *

# 服务器登录用户名和秘钥:
env.hosts = ['ec2-user@xxxx.xxxx.compute.amazonaws.com']
env.key_filename = '/xxx/xxx/xxxxxxxx.pem'

# 服务器MySQL用户名和口令:
db_user = 'root'
db_password = 'MySQL的root新用户密码'

_TAR_FILE = 'dist-awesome.tar.gz'
_REMOTE_TMP_TAR = '/tmp/%s' % _TAR_FILE
_REMOTE_BASE_DIR = '/srv/awesome'

def deploy():
    newdir = 'www-%s' % datetime.now().strftime('%y-%m-%d_%H.%M.%S')
    # 删除已有的tar文件:
    run('rm -f %s' % _REMOTE_TMP_TAR)
    # 上传新的tar文件:
    put('dist/%s' % _TAR_FILE, _REMOTE_TMP_TAR)
    # 创建新目录:
    with cd(_REMOTE_BASE_DIR):
        sudo('mkdir %s' % newdir)
    # 解压到新目录:
    with cd('%s/%s' % (_REMOTE_BASE_DIR, newdir)):
        sudo('tar -xzvf %s' % _REMOTE_TMP_TAR)
        # 需要添加权限浏览器才能访问
        sudo('chmod -R 775 static/')
        sudo('chmod 775 favicon.ico')
        # # 由于app.py的文件格式有问题,转换一下
        # run('app.py')
    # 重置软链接:
    with cd(_REMOTE_BASE_DIR):
        sudo('rm -rf www')
        sudo('ln -s %s www' % newdir)
        sudo('chown ec2-user:ec2-user www')
        sudo('chown -R ec2-user:ec2-user %s' % newdir)
    # 重启Python服务和nginx服务器:
    with settings(warn_only=True):
        sudo('supervisorctl restart awesome')
        sudo('service nginx reload')


def build():
    includes = ['static', 'templates', 'transwarp', 'favicon.ico', '*.py', '*.txt']
    excludes = ['test', '.*', '*.pyc', '*.pyo']
    local('rm -f dist/%s' % _TAR_FILE)
    with lcd(os.path.join(os.path.abspath('.'), 'www')):
        cmd = ['tar', '--dereference', '-czvf', '../dist/%s' % _TAR_FILE]
        cmd.extend(['--exclude=\'%s\'' % ex for ex in excludes])
        cmd.extend(includes)
        local(' '.join(cmd))

最后在在awesome-website目录下运行:

$ fab build
$ fab deploy
配置Supervisor

新版Supervisor 4.0.4的配置略有不同,首先要在远程服务器的用户当前目录生成初始配置supervisord.conf:

$ echo_supervisord_conf > supervisord.conf

然后添加[program:awesome]到配置文件中,配置文件如下:

[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file
chmod=0777                 ; socket file mode (default 0700)
chown=ec2-user:ec2-user       ; socket file uid:gid owner

[inet_http_server]         ; inet (TCP) server disabled by default
port=127.0.0.1:9001        ; ip_address:port specifier, *:port for all iface

[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false               ; start in foreground if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface


[supervisorctl]

[program:awesome]
command=/srv/awesome/www/app.py ; the program (relative uses PATH, can take args)
directory=/srv/awesome/www    ; directory to cwd to before exec (def no cwd)
autostart=true                ; start at supervisord start (default: true)
startsecs=3                   ; # of secs prog must stay up to be running (def. 1)

启动Supervisor:

$ supervisord -c supervisord.conf 
配置Nginx

Nginx的配置也与之前略有不同,需要修改/etc/nginx目录下的nginx.conf,域名ssl的两个秘钥可以使用之前服务器上的,拷贝到新服务器相应路径。配置文件如下:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen 80;
        server_name aodabo.tech www.aodabo.tech;
        rewrite ^(.*)$ https://aodabo.tech permanent;
   }

    server {
        listen 443 ssl;
        server_name www.aodabo.tech;
        rewrite ^(.*)$ https://aodabo.tech permanent;
   }


    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  aodabo.tech;
        root         /srv/awesome/www;

        ssl_certificate "/etc/nginx/cert/xxxxxxxx.pem";
        ssl_certificate_key "/etc/nginx/cert/xxxxxxxxx.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_prefer_server_ciphers on;

        client_max_body_size 1m;

        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        sendfile on;

        location ~* \.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$ {
        add_header Cache-Control "no-cache";
        }

        location /favicon.ico {
                root /srv/awesome/www;
                add_header 'Service-Worker-Allowed' '/';
        }

        location /manifest.json {
            root /srv/awesome/www;
        }

        location /sw.js {
            root /srv/awesome/www;
        }

        location ~ ^\/static\/.*$ {
            root /srv/awesome/www;
        }

        location / {
            proxy_pass       http://127.0.0.1:9000;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

配置完后启动Nginx服务:

$ sudo service nginx start

最后在本地再来一次:

$ fab deploy

如果个个服务都启动顺利,打开新服务器的静态ip地址就可以看到网站了。

域名关联

在你购买的域名商那里配置添加新的服务器静态ip地址,不出意外的话,马上就可以从域名打开网站了。

删除旧服务器实例

确认新服务器运行良好后,就可以关闭旧服务器,以免扣费。在aws ec2控制台选择实例并进行关闭操作(terminate),并勾选释放静态ip的选项(release Elastic IPs)。

至此服务器迁移完毕。


Powered by Aodabo Copyright © 2019.

Zhiyuan Yang. All rights reserved.