I am using these steps to migrate from a Ubuntu 16.04 32bit server (512mb) to a 64bit server (1gb) on DigitalOcean. These same steps can be used as a guide for migrating servers for any provider. Migrating is not as simple as just restoring a snapshot to a new server image because when we do that, we get the exact same 32it/512mb server. Changing from 32bit to 64bit means we must copy all files from the old (source) server to the new (destination) server. Thankfully, this is a rare case as most servers we set up now are already on 64bit servers. There are many reasons you still may go with a 32bit server if you are using 512mb or less RAM however, with DigitalOcean's new plans starting with 1gb we can just stick with 64bit servers from now on.
1. Make backup
Create a snapshot of your droplet.
2. Create a new droplet.
Create a new droplet. In the section ‘Select additional options', tick the ‘Private networking'. This will allow us to use rsync to transfer files between the two servers.
https://www.digitalocean.com/community/tutorials/how-to-set-up-and-use-digitalocean-private-networking
At this time, we will not tick any boxes in the section ‘Add your SSH keys'. More info for that is here:
https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys–2
https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-putty-on-digitalocean-droplets-windows-users
https://devops.profitbricks.com/tutorials/use-ssh-keys-with-putty-on-windows/
3. Setup the new server
Following the settings in the link below will create a new user with root privileges (instead of using ‘root') and set up public key authentication.
https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04
Optionally, we can add/transfer our source server's ssh key to the new server using private networking. Substitute ‘other_server_private_ip' with the other servers private network ip address, e.g. 10.130.59.210
$ cat ~/.ssh/id_rsa.pub | ssh other_server_private_ip "cat >> ~/.ssh/authorized_keys"
Then enter the other server's password when prompted. To check if the key was transferred, you can go to the new server and check the ‘authorized_keys' file. You can check this using WinSCP or using the command line and logging in to the new server and doing the following:
$ sudo nano ~/.ssh/authorized_keys
4. Create a list of requirements
To get a list of which services are currently running on each server:
$ service --status-all
You can now identify which services on the source server are not on the destination server. The “+” means that the service is started, the “-” means it is stopped.
5. Install needed programs and services
We inspect the source system to see if any additional repositories have been added:
$ sudo nano /etc/apt/sources.list
If you need to, add the same sources to your destination server to have the same package versions available.
Now install any all the services you need:
$ sudo apt-get update
$ sudo apt-get install ...
$ sudo apt-get install ...
...
Next, make a list of all configuration files that have been edited on the source server which will probably include files in these directories:
- /etc/nginx/sites-available/
- /etc/nginx/sites-enabled/
- /etc/nginx/snippets/
- /etc/nginx/nginx.conf
- /etc/ssl/certs/dhparam.pem
- …
Then,
cd /var/www/html
sudo chown -R www-data:www-data .
6. Transfer data
First, make a list of all directories/files that need to be copied over such as ‘/var/www/' or any other directory.
Next, we install screen on our source server (we can also install on destination server) so that we can leave it running while we continue to work. It may already be installed.
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-screen-on-an-ubuntu-cloud-server
Screen is a console application that allows you to use multiple terminal sessions within one window. The program operates within a shell session and acts as a container and manager for other terminal sessions, similar to how a window manager manages windows.
There are many situations where creating several terminal windows is not possible or ideal. You might need to manage multiple console sessions without an X server running, you might need to access many remote cloud servers easily, or you might need to monitor a running program’s output while working on some other task. All of needs are easily addressed with the power of screen.
$ apt-get update
$ apt-get install screen
To start a new screen session:
$ screen
You will be greeted with the licensing page upon starting the program. Just press “Return” or “Enter” to continue. You will be given a normal command prompt and it looks like nothing has happened. Did “screen” fail to run correctly? No, it's running. Follow the link above for more info on using screen.
Inside of your screen session (on the source server), start any rsync tasks that you anticipate taking a long time to complete. The time scale here depends on the amount of significant (non-database) data you have to transfer.
The general command you use is:
$ sudo rsync -avz /path/to/local_file/to/transfer private_ip:/path/to/destination/directory
my example:
$ sudo rsync -avz /var/www/ 10.130.59.210:/var/www
More info on rsync here:
https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories-on-a-vps
Do the same for each of the files and directories you identified in step 5. For example:
$ sudo rsync -avz /etc/nginx/sites-available/ 10.130.59.210:/etc/nginx/sites-available
$ sudo rsync -avz /etc/nginx/sites-enabled/ 10.130.59.210:/etc/nginx/sites-enabled
$ sudo rsync -avz /etc/nginx/snippets/ 10.130.59.210:/etc/nginx/snippets
$ sudo rsync -avz /etc/nginx/nginx.conf 10.130.59.210:/etc/nginx/nginx.conf
$ sudo rsync -avz /etc/ssl/certs/dhparam.pem 10.130.59.210:/etc/ssl/certs/dhparam.pem
$ sudo rsync -avz /etc/apt/apt.conf.d/50unattended-upgrades 10.130.59.210:/etc/apt/apt.conf.d/50unattended-upgrades
$ sudo rsync -avz /etc/apt/apt.conf.d/10periodic 10.130.59.210:/etc/apt/apt.conf.d/10periodic
$ sudo rsync -avz /usr/bin/letsencrypt 10.130.59.210:/usr/bin/letsencrypt
$ sudo rsync -avz /etc/letsencrypt/ 10.130.59.210:/etc/letsencrypt
...
In my case, I also deleted the ‘default' nginx server block because it is not included in my source server.
Now let's exit screen (hold down the ‘CTRL' and letter ‘a' key, release them, then press ‘k'):
$ CTRL-a k
Now we can restart nginx and reboot the server:
$ sudo service mariadb restart
$ sudo service nginx restart
$ sudo service php7.0-fpm restart
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get autoclean
$ sudo reboot
7. Dump and transfer database files
Export the database(s):
$ mysqldump -u username -p database_name > data-dump.sql
This will dump the database into your source server's home directory. Copy this file to a directory in our new destination server:
$ sudo rsync -avz ~/data-dump.sql 10.130.59.210:/home/user
Then, import the database into the destination server.
First, login to mariadb:
$ mysql -u root -p
Create the database (substitute ‘new_database' for the name of your db):
mysql> CREATE DATABASE new_database DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Now exit by pressing CTRL+D.
Now, import the database dump:
$ mysql -u username -p new_database < data-dump.sql
- username is the username you can log in to the database with
- newdatabase is the name of the freshly created database
- data-dump.sql is the data dump file to be imported, located in the current directory
Repeat this step for each database.
8. Migrate users and groups
If necessary, check this link:
https://www.digitalocean.com/community/tutorials/how-to-migrate-linux-servers-part-3-final-steps#migrate-users-and-groups
9. Migrate Iptables firewall rules
Export IPtables rules:
On the source server, use the ‘iptables-save' to export the current rules to a file named “iptables-export” in your home directory:
$ cd ~
$ sudo iptables-save > iptables-export
Copy the file to the new serverusing the scp command:
$ scp iptables-export user@server_b_ip_address:/tmp
my example:
$ scp iptables-export 10.130.59.210:/home/user
With the exported rules on the destination server, you can load them into iptables. However, depending on your situation, you may want update the rules in the file with new IP addresses and ranges, and perhaps update interface names. If you want to change the rules before loading them, be sure to edit the /tmp/iptables-export file now
On the destination server, import Iptables rules:
$ cd ~
$ sudo iptables-restore < /home/user/iptables-export
$ sudo apt-get install iptables-persistent
During the installation, you will asked if you want to save your current firewall rules. Response yes, if you want to save the current rule set.
If you update your firewall rules in the future, and want to save the changes, run this command:
$ sudo invoke-rc.d iptables-persistent save
10. Finishing up
A. From DigitalOcean go to the ‘Networking' section, click the site you would like to change over to the new destination server, and edit the A records to reflect the new ip (ipv4) address of the new server. (There should be a drop down menu with a list of droplets to choose from.)
B. If using Cloudflare as a CDN, login to your account and go to the ‘DNS' section. Edit the A records here to reflect the new ip address.
Follow steps A and B for each site that will be hosted on the new server.
References
https://www.digitalocean.com/community/tutorials/how-to-migrate-linux-servers-part-1-system-preparation
https://www.digitalocean.com/community/tutorials/how-to-migrate-linux-servers-part-2-transfer-core-data
https://www.digitalocean.com/community/tutorials/how-to-migrate-linux-servers-part-3-final-steps