-
Notifications
You must be signed in to change notification settings - Fork 37
Blog Deployment & Migration
-
Launch an EC2 instance with the pre-made "WordPress powered by Bitnami (HVM)" configuration, which is available on the AWS Marketplace. The instance should be a t2.micro. Copy the initial bitnami randomly-generated password, and optionally change it, so you can sub it in later.
-
Add it to the existing "blog" VPC and Subnet, and give it the "blog" IAM role. Among other things, that IAM role is associated with a policy that grants write access to the "overview-blog" bucket on S3, for backups.
-
Disable the banner from the bitnami install: https://wiki.bitnami.com/Components/Bitnami_info_page
-
If applicable, restore our Wordpress customizations and the blog database. (See below.)
-
Set up backups to run in the future, as follows:
-
SSH into the server, using bitnami's standard instructions.
-
Install modules that the backup script needs, and create the
tmp
directory:
apt-get install python-pip
pip install boto
pip install FileChunkIO
mkdir /home/bitnami/tmp
- Create the backup script in
/home/bitnami/scripts/
and call itbackup.py
. The content's of the script should be:
#!/usr/bin/python
import sys
import os
import boto
import math
import smtplib
from email.mime.text import MIMEText
from subprocess import check_call, CalledProcessError
from boto.s3.key import Key
from datetime import datetime
from filechunkio import FileChunkIO
# Create an email helper we'll use if the backup fails
def email_error(error_string):
from_addr = "admin@overviewproject.org";
to_addr = "studip101@gmail.com";
msg = MIMEText("The exact error was: " + error_string)
msg['subject'] = "Overview Blog Backup failed!";
msg['From'] = from_addr;
msg['To'] = to_addr;
SMTP_USERNAME=PUT_SMTP_USERNAME_HERE
SMTP_PASSWORD=PUT_SMTP_PASSWORD_HERE
smtpObj = smtplib.SMTP("email-smtp.us-east-1.amazonaws.com")
smtpObj.starttls()
smtpObj.login(SMTP_USERNAME, SMTP_PASSWORD)
smtpObj.sendmail(from_addr, [to_addr], msg.as_string())
smtpObj.quit();
sys.exit("encountered an error...emailing it and terminating")
# Create the backup files in tmp.
# Note: path names aren't portably joined, but who cares.
dir = os.path.abspath(os.path.dirname(__file__))
wordpress_src_glob = os.path.normpath(dir + "/../apps/wordpress/*")
wordpress_tar_dst = os.path.normpath(dir + "/../tmp/wordpress-app-with-certs.tar.gz")
sql_dump_dst = os.path.normpath(dir + "/../tmp/db-dump.sql")
try:
check_call("sudo mysqldump --user=root --password=PASSWORD_FOR_DB bitnami_wordpress > " + sql_dump_dst, shell=True)
check_call("tar -cvzf " + wordpress_tar_dst + " " + wordpress_src_glob + "", shell=True)
except CalledProcessError as e:
email_error('"{0}" returned with code {1}'.format(e.cmd, e.returncode))
# Connect to S3
s3 = boto.connect_s3()
bucket = s3.get_bucket('overview-blog')
# Do the S3 uploads, in chunks
def do_multipart_upload(source_path):
try:
chunk_size = 52428800
source_size = os.stat(source_path).st_size
chunk_count = int(math.ceil(source_size / float(chunk_size)))
mp = bucket.initiate_multipart_upload(os.path.basename(source_path))
for i in range(chunk_count):
offset = chunk_size*i
bytes = min(chunk_size, source_size - offset)
with FileChunkIO(source_path, 'r', offset=offset, bytes=bytes) as fp:
mp.upload_part_from_file(fp, part_num=i + 1)
mp.complete_upload()
return True
except:
email_error("Problem uploading to s3; check the backup file to debug further.");
do_multipart_upload(wordpress_tar_dst)
do_multipart_upload(sql_dump_dst)
Of course, you need to sub in the password for the database where it says PASSWORD_FOR_DB
above.
-
Register the above script as a cronjob: 1.
crontab -e
2. Add the line:0 3 * * * /home/bitnami/scripts/backup.py
-
That's it!
Assuming you're starting with a default bitnami install (per above), all you have to do is:
- Replace the contents of
/home/bitnami/apps/wordpress
with the latest version ofwordpress-app-with-certs.tar.gz
from the S3 overview-blog bucket - Restore the
bitnami_wordpress
database from the latest version of the db-dump.sql file from S3.
If you need to restore from an older backup (i.e. not the latest version), those can be accessed through S3's versioning system.
Other than re-pointing DNS, future migrations will require adding a redirect from the old URIs to the new ones. A simple way to do this is to leave the old domain name pointing to the new blog instance as well, but add some redirects in .htaccess
for the old TLD. Additionally, you may want to edit the URIs in the body of the post's themselves, though this isn't strictly necessary if the aforementioned redirect is in place. However, if you do decide to edit the URIs, make sure the resulting URIs remain absolute (just pointed to the new domain). Yes, this is a bit of a pain, since using relative URIs would prevent the need for future rewrites, but absolute uris are needed in some rss readers that don't properly honor xml:base
, which wasn't originally discussed in the RSS 2 spec.