Skip to content

Commit b8e6422

Browse files
slotixsvenja11
andauthored
✨ New tutorial - "How to Transfer Your Database to Hetzner Cloud" (#1137)
* ✨ Add new tutorial on transferring databases to Hetzner Cloud * Introduced a comprehensive guide for migrating databases to Hetzner Cloud using DBConvert Streams. * Spelling and formatting updates * Update date --------- Co-authored-by: svenja.michal <84835304+svenja11@users.noreply.github.com>
1 parent ea1603a commit b8e6422

File tree

6 files changed

+394
-0
lines changed

6 files changed

+394
-0
lines changed
Lines changed: 394 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,394 @@
1+
---
2+
SPDX-License-Identifier: MIT
3+
path: "/tutorials/how-to-transfer-database-to-hetzner-cloud"
4+
slug: "how-to-transfer-database-to-hetzner-cloud"
5+
date: "2025-05-20"
6+
title: "How to Transfer Your Database to Hetzner Cloud"
7+
short_description: "Easily migrate your database to Hetzner with DBConvert Streams. Follow this guide to transfer your data securely and efficiently while reducing hosting costs."
8+
tags: ["Database", "MySQL", "PostgreSQL", "Docker", "Migration"]
9+
author: "Dmitry Narizhnykh"
10+
author_link: "https://github.com/slotix"
11+
author_img: "https://avatars.githubusercontent.com/u/684169"
12+
author_description: "Founder and CEO of DBConvert. Building tools for effortless database migration and replication across different platforms."
13+
language: "en"
14+
available_languages: ["en"]
15+
header_img: "header-8"
16+
cta: "cloud"
17+
---
18+
19+
## Introduction
20+
21+
If you're currently hosting your database on another cloud provider and watching your monthly bills grow, migrating to Hetzner can dramatically reduce your costs while potentially improving performance. Many users report equivalent or better performance compared to much more expensive cloud options, especially for database workloads.
22+
23+
In this guide, I'll walk you through transferring your databases to Hetzner using [DBConvert Streams](https://docs.dbconvert.com/) — a powerful database migration platform designed to simplify moving data between different hosting environments and database types.
24+
25+
**Prerequisites**
26+
27+
Before you start, make sure you have:
28+
29+
* An [account with DBConvert](https://streams.dbconvert.com/) (free trial for 14 days)
30+
* A Hetzner Cloud account
31+
* Your source database credentials (e.g., AWS RDS, Google Cloud SQL, Azure DB)
32+
* Basic familiarity with Linux commands
33+
* [SSH key](https://community.hetzner.com/tutorials/howto-ssh-key) added to your Hetzner Cloud account
34+
35+
**Example terminology**
36+
37+
* Server: `<10.0.0.1>`
38+
39+
## Step 1 - Create a Hetzner Cloud Server
40+
41+
First, let's create a Hetzner [cloud server with Docker pre-installed](https://console.hetzner.cloud/deploy/docker-ce).
42+
43+
> For a step-by-step guide, see [this getting started](https://docs.hetzner.com/cloud/servers/getting-started/creating-a-server).
44+
45+
* For the image, choose the "Apps" tab and select "Docker CE"
46+
* Select a server type based on your database needs:
47+
* For development/small production databases: CPX21 (2 vCPU, 4GB RAM)
48+
* For medium workloads: CPX31 (4 vCPU, 8GB RAM)
49+
* For larger production databases: CPX41 (8 vCPU, 16GB RAM)
50+
* Add your SSH key or create a new one
51+
52+
**Note:** The "CPX" line is recommended for database workloads as they offer NVMe SSD storage with higher I/O performance compared to the standard "CX" instances.
53+
54+
## Step 2 - Set Up PostgreSQL on Hetzner
55+
56+
For simplicity in this tutorial, we'll deploy both [DBConvert Streams](https://github.com/slotix/dbconvert-streams-public) and our target PostgreSQL database on the same server.
57+
58+
1. SSH into your new Hetzner server:
59+
60+
> Replace `<10.0.0.1>` with the IP address of your cloud server.
61+
62+
```bash
63+
ssh root@<10.0.0.1>
64+
```
65+
66+
2. Create directories for PostgreSQL data and configuration:
67+
68+
```bash
69+
mkdir -p ~/pg-data ~/pg-conf
70+
```
71+
72+
3. Run PostgreSQL in Docker:
73+
74+
```bash
75+
docker run -d \
76+
--name postgres \
77+
-e POSTGRES_USER=pguser \
78+
-e POSTGRES_PASSWORD=strongpassword \
79+
-e POSTGRES_DB=mydb \
80+
-v ~/pg-data:/var/lib/postgresql/data \
81+
-p 5432:5432 \
82+
postgres:16
83+
```
84+
85+
Make sure to replace `strongpassword` with a secure password and `mydb` with your desired database name.
86+
87+
4. Verify PostgreSQL is running:
88+
89+
```bash
90+
docker ps
91+
```
92+
93+
You should see your PostgreSQL container running on port 5432.
94+
95+
## Step 3 - Deploy DBConvert Streams
96+
97+
Now, let's install DBConvert Streams on the same server:
98+
99+
1. Download and install DBConvert Streams:
100+
101+
```bash
102+
curl -fsSL https://dbconvert.nyc3.digitaloceanspaces.com/downloads/streams/latest/docker-install.sh | sh
103+
```
104+
105+
<details>
106+
<summary>Click here to view the output</summary>
107+
108+
```shellsession
109+
root@example-server:~# curl -fsSL https://dbconvert.nyc3.digitaloceanspaces.com/downloads/streams/latest/docker-install.sh | sh
110+
Installing gum using binary installation...
111+
112+
┌──────────────────────────────────────────────────────────────┐
113+
│ │
114+
│ Welcome to DBConvert Streams Installation │
115+
│ This wizard will guide you through the installation process. │
116+
│ │
117+
└──────────────────────────────────────────────────────────────┘
118+
119+
Checking latest available version...
120+
Latest version available: v1.3.0
121+
122+
┌──────────────────────────────────────────┐
123+
│ │
124+
│ Installing DBConvert Streams │
125+
│ Version: v1.3.0 │
126+
│ Directory: /opt/dbconvert-streams-docker │
127+
│ │
128+
└──────────────────────────────────────────┘
129+
130+
Starting installation...
131+
Installing DBConvert Streams...
132+
Checking prerequisites...
133+
Downloading deployment files...
134+
Updating version information in .env file...
135+
136+
[...]
137+
138+
Self-signed certificate generated successfully!
139+
Private key: config/certs/private.key
140+
Certificate: config/certs/certificate.crt
141+
Setting up nginx configuration...
142+
Configuring nginx with HTTP only...
143+
Nginx configuration complete!
144+
Installation complete!
145+
DBConvert Streams Version Information
146+
147+
Latest available version:
148+
Latest version: v1.3.0
149+
150+
Configured versions in .env file:
151+
streams: v1.3.0
152+
stream-ui: v1.3.2
153+
154+
No DBConvert Streams services are currently running
155+
156+
┌──────────────────────────────────────────────────────────────────────────────────┐
157+
│ │
158+
│ Installation Complete! │
159+
│ Your DBConvert Streams installation is ready. │
160+
│ │
161+
│ To start the services: │
162+
│ 1. Change to the installation directory: │
163+
│ cd /opt/dbconvert-streams-docker │
164+
│ 2. Run the start script: │
165+
│ For HTTP: ./start.sh │
166+
│ For HTTPS: ./start.sh --secure │
167+
│ │
168+
│ You can switch between HTTP and HTTPS modes at any time using the --secure flag. │
169+
│ │
170+
└──────────────────────────────────────────────────────────────────────────────────┘
171+
```
172+
173+
</details>
174+
175+
2. Navigate to the installation directory and start the services:
176+
177+
```bash
178+
cd /opt/dbconvert-streams-docker/
179+
./start.sh
180+
```
181+
182+
After the services start up, you'll see a message with your service URLs:
183+
184+
```
185+
┌────────────────────────────────────────────────────────────────────┐
186+
│ │
187+
│ Service URLs │
188+
│ │
189+
│ • UI: http://<10.0.0.1> │
190+
│ • API: http://<10.0.0.1>/api/ │
191+
│ │
192+
│ Setup complete! You can now access the services at the URLs above. │
193+
│ │
194+
└────────────────────────────────────────────────────────────────────┘
195+
```
196+
197+
## Step 4 - Obtain and Enter Your API Key
198+
199+
1. Go to https://streams.dbconvert.com/account
200+
2. Sign in using your preferred authentication method
201+
3. Copy your API key from the account dashboard
202+
4. Return to your DBConvert Streams instance:
203+
```http
204+
http://<10.0.0.1>
205+
```
206+
5. Paste the API key in the provided field
207+
208+
DBConvert Streams offers a free trial that includes:
209+
* 5GB of data transfer
210+
* 14 days of unlimited access to all features
211+
* No credit card required to start
212+
213+
## Step 5 - Connect Your Source Database
214+
215+
### Step 5.1 - Configure Source Database Access
216+
217+
Make sure DBConvert Streams can can access your source database.
218+
219+
This step is different, depending on your provider.
220+
221+
* Google Cloud SQL MySQL
222+
223+
1. In the Google Cloud Console, navigate to your Cloud SQL instance
224+
2. Go to the "Connections" tab
225+
3. Under "Networking," select "Add network"
226+
4. Add your Hetzner server's IP address
227+
5. Save your changes
228+
229+
![add network](images/add-network.png)
230+
231+
### Step 5.2 - Create the Source Connection
232+
233+
1. Return to your DBConvert Streams instance:
234+
```http
235+
http://<10.0.0.1>
236+
```
237+
2. Click the quick action "Create Connection" in the dashboard
238+
3. Select your database type (e.g., MySQL)
239+
4. Enter your connection details:
240+
* Name: Optional. Give your connection a descriptive name
241+
* Server: Your source database IP/hostname
242+
* Port: Database port (e.g., 3306 for MySQL)
243+
* User ID: Your database username
244+
* Password: Your database password
245+
* Database: Source database name
246+
5. Click "Add"
247+
6. Test the connection
248+
7. Click "Update" to store the connection
249+
250+
![create source connection](images/create-source-connection.png)
251+
252+
## Step 6 - Connect Your Hetzner PostgreSQL Database
253+
254+
1. Return to the dashboard
255+
2. Click the quick action "Create Connection" in the dashboard
256+
3. Select "PostgreSQL"
257+
4. Enter the connection details:
258+
* Host: Your Hetzner server IP
259+
* Port: 5432
260+
* Username: pguser
261+
* Password: Your PostgreSQL password
262+
* Database: mydb
263+
5. Click "Add"
264+
6. Test the connection
265+
7. Click "Update" to save the configuration
266+
267+
![create target connection](images/create-target-connection.png)
268+
269+
## Step 7 - Configure Your Data Stream
270+
271+
1. Return to the dashboard
272+
2. Click "Create New Stream"
273+
3. Select your source connection and click "Next" in the top right
274+
4. Choose tables to migrate
275+
276+
Select transfer mode:
277+
* Convert/Migrate: For one-time migrations
278+
* CDC/Stream: For continuous replication
279+
280+
Configure options:
281+
* Data bundle size
282+
* Index creation options
283+
* Custom SQL queries (if needed)
284+
285+
When you're happy with your settings, click "Next" in the top right
286+
287+
5. Select your target Hetzner PostgreSQL connection and click "Save" in the top right
288+
289+
![create stream](images/create-stream.png)
290+
291+
## Step 8 - Start and Monitor the Transfer
292+
293+
1. Click the "Start" button to begin
294+
2. Monitor the transfer through the dashboard:
295+
* Track progress for each table
296+
* Monitor data transfer rates
297+
* View detailed logs
298+
* Pause or stop if needed
299+
300+
![monitor stream](images/monitor-stream.png)
301+
302+
## Step 9 - Verify Your Data
303+
304+
1. Connect to your PostgreSQL database:
305+
306+
```bash
307+
docker exec -it postgres psql -U pguser -d mydb
308+
```
309+
310+
2. Run verification queries:
311+
312+
```sql
313+
-- List all tables in the database
314+
\dt
315+
316+
-- Get row counts for all tables
317+
SELECT
318+
schemaname as schema,
319+
relname as table_name,
320+
n_live_tup as row_count
321+
FROM pg_stat_user_tables
322+
ORDER BY n_live_tup DESC;
323+
324+
-- Check table sizes including indexes
325+
SELECT
326+
table_schema,
327+
table_name,
328+
pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) as total_size
329+
FROM information_schema.tables
330+
WHERE table_schema = 'public'
331+
ORDER BY pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC;
332+
```
333+
334+
3. Compare these results with your source database to ensure:
335+
336+
- All tables are present
337+
- Row counts match
338+
- Data sizes are reasonable
339+
- Primary keys and indexes are properly transferred
340+
341+
If the numbers don't match or you notice any discrepancies, you may need to investigate specific tables in more detail.
342+
343+
## Step 10 - Set Up Database Backups
344+
345+
### Hetzner Snapshots
346+
347+
1. In Hetzner Cloud Console, select your server
348+
2. Click "Snapshots"
349+
3. Click "Create Snapshot"
350+
351+
See Snapshot prices at [hetzner.com/cloud](https://www.hetzner.com/cloud/#features).
352+
353+
## Conclusion
354+
355+
You've successfully migrated your database to Hetzner Cloud using DBConvert Streams. This setup provides you with:
356+
357+
* Significant cost savings compared to other cloud providers
358+
* Full control over your database infrastructure
359+
* Automated backups for data security
360+
* High-performance NVMe storage
361+
* Simple management through Docker containers
362+
363+
Remember to monitor your database performance and adjust server resources as needed. You can easily scale your Hetzner server up or down based on your workload requirements.
364+
365+
##### License: MIT
366+
367+
<!--
368+
369+
Contributor's Certificate of Origin
370+
371+
By making a contribution to this project, I certify that:
372+
373+
(a) The contribution was created in whole or in part by me and I have
374+
the right to submit it under the license indicated in the file; or
375+
376+
(b) The contribution is based upon previous work that, to the best of my
377+
knowledge, is covered under an appropriate license and I have the
378+
right under that license to submit that work with modifications,
379+
whether created in whole or in part by me, under the same license
380+
(unless I am permitted to submit under a different license), as
381+
indicated in the file; or
382+
383+
(c) The contribution was provided directly to me by some other person
384+
who certified (a), (b) or (c) and I have not modified it.
385+
386+
(d) I understand and agree that this project and the contribution are
387+
public and that a record of the contribution (including all personal
388+
information I submit with it, including my sign-off) is maintained
389+
indefinitely and may be redistributed consistent with this project
390+
or the license(s) involved.
391+
392+
Signed-off-by: Dmitry Narizhnykh <streams@dbconvert.com>
393+
394+
-->
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)