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, 如下图所示:
。添加HTTP和HTTPS是为了以后访客可以从80和433端口访问到网站服务器。SSH端口则是为了网站主与服务器进行远程命令行操控或传输。
- 申请静态ip地址(Elastic IPs), 在页面左边的菜单中选择Elastic IPs, 并 Allocate new address, 选项中勾选关联现有的服务器实例(instance)。
远程服务器配置
为了从本地连接服务器博主使用了SecureCRT来进行SSH的链接,配置时需要填写服务器的Hostname, Username, 并选择之前现在的.pem文件作为PublicKey进行连接。配置如图所示: 。
一旦连接上就可以对服务器进行远程操作了,过程跟[部署服务器教程]中的类似。不同的是,在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)。
至此服务器迁移完毕。