← Back to posts

Import Your PostgreSQL Database to a Hetzner VM

Migrating databases can often seem like a daunting task, but with the right tools and a clear set of instructions, it can be a smooth and straightforward process. In this blog post, I'll explore the steps of importing a PostgreSQL database into a Hetzner virtual machine (VM).

Prerequisits

You need to have a pg_dump dumpfile (e.g. my-backup.sql) in the root directory, from where you'll access your VM. E.g. if you have a rails app, just temporarily put the sql file in your root directory. How to get the dumpfile in the first place? This post looks at a few options..

Step 1: Transfer the Database Dump to the Target VM

With the database dump file created and stored in your current directory from where you're going to access your Hetzner VM, the next step is to transfer it to your target VM. The scp command facilitates the secure copying of files between hosts on a network. Execute the following command, ensuring to replace target-vm-ip with your target VM's IP address, filename.sql with your dump file's name, and /path/to/destination with the desired path on the target VM.

scp filename.sql user@target-vm-ip:/path/to/destination

In our case this should look something like this:

scp your-backup.sql root@73.37.73.112:~/

Step 2: Import the Database on the Target VM

Now, it's time to switch over to your target VM. SSH into the target VM using:

ssh user@target-vm-ip

Or somthing like this:

ssh root@73.37.73.112

Navigate to the directory containing the dump file:

If you followed the previous instructions, the dump file should be in the root's home directory. You can check by running:

ls -l ~/your-backup.sql

Step 3: Identify the Docker container running PostgreSQL

Since in our case we're running several Docker containers on our Hetzner VM (following this post), and our Database has its own Docker container, we need to identify, which container we're going to migrate our dump file to. So still sshed into our Hetzer VM, check all the running Docker container:

docker ps

This should give you a list of all containers, including a 'Container ID'. Find the one containing the name of your app and that has a postgres image and copy its ID.

Step 4: Access the PostgreSQL Database Shell

Access the PostgreSQL shell using the ocker exec command. Replace your_postgres_container with the actual name or ID of your PostgreSQL Docker container from the previous step.

docker exec -it your_postgres_container psql -U your_app_user -d your_app_production

You should find your_app_user and your_app_production in your deploy.yml file as the values of POSTGRES_USER: and POSTGRES_DB:.

Step 5: Drop the Existing Database Tables (DANGER!!)

Once inside the PostgreSQL shell, you can drop all tables or use the dropdb and createdb commands. But be careful, this destroy the current database!! If you want to replace the current DB with the data from your pg_dump, you'll have to drop all tables, by doing this:

DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO your_app_user;
GRANT ALL ON SCHEMA public TO public;

Replace your_app_user with your actual pg user, as described in the previous step, execute the SQL query and then quit the PostgreSQL shell (\q + Enter)

Step 6: Import the Database Dump

Use the docker exec command to import the SQL file into your PostgreSQL container. Replace your_postgres_container with the actual container name or ID, and make sure the path to your SQL dump file is correct, which in our case should be the directory from which we've SSHed into our VM:

cat ~/your-backup.sql | docker exec -i your_postgres_container psql -U your_app_user -d your_app_production

Additional Notes:

  • Replace user with the appropriate username for SSH access to your VMs.
  • You may need to provide your SSH password or use an SSH key for authentication.
  • If your PostgreSQL setup requires a username and password, append the -U username option to both the pg_dump and psql commands.
  • Make sure the PostgreSQL service is running on the target VM before attempting to import the database.
  • If your VMs are not on the same local network, you might need to configure firewall rules to allow SSH and PostgreSQL traffic.
  • Here's how you might include the username in your commands if needed: pg_dump -U username dbname > filename.sql psql -U username dbname < /path/to/destination/filename.sql When prompted, enter the password for the PostgreSQL user.

Optional

Before importing, make sure that the PostgreSQL service is running on your VM. If it's not running, start it with:

service postgresql start

Install require packages:

sudo apt-get update
sudo apt install postgresql-client-common
sudo apt-get install -y postgresql-client