diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationController.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationController.java
index 321225c9a5a583f5bb3281589f487cf97b9bce2d..2e2cecf024cfd07edfdf859aae4ee65aab4a7c85 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationController.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationController.java
@@ -5,16 +5,29 @@ import de.deadlocker8.budgetmaster.settings.SettingsService;
 import de.deadlocker8.budgetmaster.utils.Mappings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
 
 
 @Controller
 @RequestMapping(Mappings.MIGRATION)
 public class MigrationController extends BaseController
 {
+	private static class ModelAttributes
+	{
+		public static final String ERROR = "error";
+		public static final String MIGRATION_SETTINGS = "migrationSettings";
+	}
+
+	private static class ReturnValues
+	{
+		public static final String MIGRATION_SETTINGS = "migration";
+	}
+
 	private final SettingsService settingsService;
 
 	@Autowired
@@ -31,8 +44,33 @@ public class MigrationController extends BaseController
 	}
 
 	@GetMapping
-	public String migrate()
+	public String migrate(Model model)
 	{
-		return "migration";
+		model.addAttribute(ModelAttributes.MIGRATION_SETTINGS, new MigrationSettings(null, null, null, null, null));
+		return ReturnValues.MIGRATION_SETTINGS;
+	}
+
+	@PostMapping
+	public String post(Model model,
+					   @ModelAttribute("MigrationSettings") @Valid MigrationSettings migrationSettings, BindingResult bindingResult,
+					   @RequestParam(value = "verificationPassword") String verificationPassword)
+	{
+		// TODO validate verification password
+//		final Optional<FieldError> passwordErrorOptional = settingsService.validatePassword(password, passwordConfirmation);
+//		passwordErrorOptional.ifPresent(bindingResult::addError);
+
+
+		final MigrationSettingsValidator migrationSettingsValidator = new MigrationSettingsValidator();
+		migrationSettingsValidator.validate(migrationSettings, bindingResult);
+
+		if(bindingResult.hasErrors())
+		{
+			model.addAttribute(ModelAttributes.ERROR, bindingResult);
+			model.addAttribute(ModelAttributes.MIGRATION_SETTINGS, migrationSettings);
+			return ReturnValues.MIGRATION_SETTINGS;
+		}
+
+		// TODO
+		return ReturnValues.MIGRATION_SETTINGS;
 	}
 }
\ No newline at end of file
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettings.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettings.java
new file mode 100644
index 0000000000000000000000000000000000000000..c909cb3fab96c6115d9299e8e5627760a3075ddf
--- /dev/null
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettings.java
@@ -0,0 +1,5 @@
+package de.deadlocker8.budgetmaster.migration;
+
+public record MigrationSettings(String hostname, Integer port, String databaseName, String username, String password)
+{
+}
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettingsValidator.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettingsValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a7f3687aa720d486005e2f6c639688f9cc42b62
--- /dev/null
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/migration/MigrationSettingsValidator.java
@@ -0,0 +1,24 @@
+package de.deadlocker8.budgetmaster.migration;
+
+import de.deadlocker8.budgetmaster.utils.Strings;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+
+public class MigrationSettingsValidator implements Validator
+{
+	public boolean supports(Class clazz)
+	{
+		return MigrationSettings.class.equals(clazz);
+	}
+
+	public void validate(Object obj, Errors errors)
+	{
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "hostname", Strings.WARNING_EMPTY_MIGRATION_HOSTNAME);
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "port", Strings.WARNING_EMPTY_NUMBER);
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "databaseName", Strings.WARNING_EMPTY_MIGRATION_DATABASE_NAME);
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", Strings.WARNING_EMPTY_MIGRATION_USERNAME);
+		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", Strings.WARNING_EMPTY_MIGRATION_PASSWORD);
+	}
+}
\ No newline at end of file
diff --git a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
index a8d059ae95ff5e94a07ebbd0e9cfaa4081b9fa64..14e3cfc24baebb058fa5e8e92d46f314d4ed8dc4 100644
--- a/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
+++ b/BudgetMasterServer/src/main/java/de/deadlocker8/budgetmaster/utils/Strings.java
@@ -38,6 +38,12 @@ public class Strings
 	public static final String WARNING_EMPTY_GIT_USER_NAME = "warning.empty.git.user.name";
 	public static final String WARNING_EMPTY_GIT_TOKEN = "warning.empty.git.token";
 
+	public static final String WARNING_EMPTY_MIGRATION_HOSTNAME = "warning.empty.migration.hostname";
+	public static final String WARNING_EMPTY_MIGRATION_DATABASE_NAME = "warning.empty.migration.databaseName";
+	public static final String WARNING_EMPTY_MIGRATION_USERNAME = "warning.empty.migration.username";
+	public static final String WARNING_EMPTY_MIGRATION_PASSWORD = "warning.empty.migration.password";
+
+
 	//REPORT
 	public static final String REPORT_FOOTER_LEFT = "report.footer.left";
 	public static final String REPORT_FOOTER_CENTER = "report.footer.center";
diff --git a/BudgetMasterServer/src/main/resources/languages/base_de.properties b/BudgetMasterServer/src/main/resources/languages/base_de.properties
index 01ad3d3eb35fb1304577bb396b5ea72f3ab3d677..fb7442c89b4138a2284fdd913e983d8784b79b02 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_de.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_de.properties
@@ -164,7 +164,7 @@ info.title.backup.reminder=Zeit für ein Backup
 info.text.backup.reminder=Schon mal über ein Backup nachgedacht?<br>Du solltest deine BudgetMaster Datenbank regelmäßig sichern.<br>Dies geht besonders einfach in den Einstellungen.<br>Du kannst auch ein automatisches Backup konfigurieren.<br><br>(Du wilst diese Erinnerung nicht jeden Monat sehen? Dann deaktiviere die Backuperinnerung in den Einstellungen.)
 info.button.backup.reminder=Zu den Einstellungen
 info.title.migration=Kommst du von einer früheren Version?
-info.text.migration=BudgetMaster 2.10.0 führt ein neues Datenbank-Backend ein.<br>Deine aktuelle Datenbank scheint leer zu sein.<br>Hast du BudgetMaster bereits vor Version 2.10.0 benutzt und möchtest deine bestehende Datenbank migrieren?<br><br><span class="text-red bold">ACHTUNG: Wenn du diesen Dialog abbrichst, wirst du nicht mehr nach der Migration gefragt!</span>
+info.text.migration=BudgetMaster 2.10.0 führt ein neues Datenbank-Backend ein.<br>Deine aktuelle Datenbank scheint leer zu sein.<br>Hast du BudgetMaster bereits vor Version 2.10.0 benutzt und möchtest deine bestehende Datenbank migrieren?<br><br><span class="red-text bold">ACHTUNG: Wenn du diesen Dialog abbrichst, wirst du nicht mehr nach der Migration gefragt!</span>
 info.button.migration=Bestehende Datenbank migrieren
 notification.settings.saved=Einstellungen gespeichert
 notification.settings.update.available=BudgetMaster Update "{0}" verfügbar
@@ -214,6 +214,10 @@ warning.empty.git.url=Bitte gib die URL zum git-Server ein.
 warning.empty.git.branch.name=Bitte gib den Namen des git-Branches ein.
 warning.empty.git.user.name=Bitte gib deinen git-Nutzernamen ein.
 warning.empty.git.token=Bitte gib dein git-Zugriffstoken ein.
+warning.empty.migration.hostname=Bitte gib den Hostnamen des Datenbankservers ein.
+warning.empty.migration.databaseName=Bitte gib den Namen der Datenbank ein.
+warning.empty.migration.username=Bitte gib den Nutzernamen ein.
+warning.empty.migration.password=Bitte gib das Datenbankpasswort ein.
 
 
 # UI
@@ -630,3 +634,11 @@ import.entity.image=Icons werden automatisch mit den zugehörigen Konten, Vorlag
 import.entity.chart=Es werden nur die benutzerdefinierten Diagramme importiert.<br>Der Import von Diagrammen ist optional.
 
 copied=Kopiert!
+
+migration.settings.description=Alle Daten aus deiner bestehenden BudgetMaster Datenbank werden in die neue Datenbank migriert.<br> Bitte gib die Einstellungen für das neue Datenbank-Backend (z.B. postgresql) ein.
+migration.settings.hostname=Hostname
+migration.settings.port=Port
+migration.settings.databaseName=Datenbankname
+migration.settings.username=Nutzername
+migration.settings.password=Passwort
+migration.settings.verification.password=Bisheriges BudgetMaster Passwort
diff --git a/BudgetMasterServer/src/main/resources/languages/base_en.properties b/BudgetMasterServer/src/main/resources/languages/base_en.properties
index 0623ebde5fff90d5496d47db2a2ec2894da79f46..c897ac0108f222a9ba3240a6f628d41e8b6fa99c 100644
--- a/BudgetMasterServer/src/main/resources/languages/base_en.properties
+++ b/BudgetMasterServer/src/main/resources/languages/base_en.properties
@@ -165,7 +165,7 @@ info.title.backup.reminder=Time for a backup
 info.text.backup.reminder=Have you ever thought about a backup?<br>You should back up your BudgetMaster database regularly.<br>This can be done on the settings page.<br>You can also enable an automatic backup.<br><br>(You don''t want to see this reminder every month? Disable the backup reminder in the settings.)
 info.button.backup.reminder=To the settings
 info.title.migration=Are you coming from a previous version?
-info.text.migration=BudgetMaster 2.10.0 introduces a new database backend.<br>Your current database seems to be empty.<br>Have you used BudgetMaster before version 2.10.0 and want to migrate your existing database?<br><br> <span class="text-red bold">CAUTION: If you cancel this dialog, you will not be asked again about the migration!</span>
+info.text.migration=BudgetMaster 2.10.0 introduces a new database backend.<br>Your current database seems to be empty.<br>Have you used BudgetMaster before version 2.10.0 and want to migrate your existing database?<br><br> <span class="red-text bold">CAUTION: If you cancel this dialog, you will not be asked again about the migration!</span>
 info.button.migration=Migrate existing database
 notification.settings.saved=Settings saved
 notification.settings.update.available=BudgetMaster update "{0}" available
@@ -213,8 +213,12 @@ warning.duplicate.template.name=A template with this name is already existing.
 warning.transaction.date=The specified date does not correspond to the allowed format. Expected format: DD.MM.YY, DDMMYY, DD.MM.YYYY, DDMMYYYY.
 warning.empty.git.url=Please insert the git server's URL.
 warning.empty.git.branch.name=Please insert the git branch name.
-warning.empty.git.user.name=Please insert your git user name.
+warning.empty.git.user.name=Please insert your git username.
 warning.empty.git.token=Please insert your git access token.
+warning.empty.migration.hostname=Please insert the hostname of the database server.
+warning.empty.migration.databaseName=Please insert the database name
+warning.empty.migration.username=Please insert the username.
+warning.empty.migration.password=Please insert the database password.
 
 
 # UI
@@ -629,3 +633,11 @@ import.entity.image=Icons are automatically imported with their associated accou
 import.entity.chart=Only user-defined charts will be imported.<br>The import of charts is optional.
 
 copied=Copied!
+
+migration.settings.description=All data from your existing BudgetMaster database will be migrated to the new database.<br> Please enter the settings for the new database backend (e.g. postgresql).
+migration.settings.hostname=Hostname
+migration.settings.port=Port
+migration.settings.databaseName=Database name
+migration.settings.username=Username
+migration.settings.password=Password
+migration.settings.verification.password=Current BudgetMaster password
diff --git a/BudgetMasterServer/src/main/resources/templates/migration.ftl b/BudgetMasterServer/src/main/resources/templates/migration.ftl
index 4aa039d958ea67e77dab099425be8b18cade3be2..d152179b4158fd462ea87f4122247da049960044 100644
--- a/BudgetMasterServer/src/main/resources/templates/migration.ftl
+++ b/BudgetMasterServer/src/main/resources/templates/migration.ftl
@@ -8,6 +8,7 @@
     <@header.body>
         <#import "helpers/navbar.ftl" as navbar>
         <@navbar.navbar "migration" settings/>
+        <#import "helpers/validation.ftl" as validation>
 
         <main>
             <div class="card main-card background-color">
@@ -16,15 +17,61 @@
                         <div class="headline">${locale.getString("title.migration")}</div>
                     </div>
                 </div>
-
                 <div class="container">
-                    <form name="Import" action="<@s.url '/migration/start'/>" method="post">
+                    <form name="MigrationSettings" action="<@s.url '/migration'/>" method="post">
                         <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
 
                         <div class="row">
-                            <div class="col s12 m10 offset-m1 l10 offset-l1 xl8 offset-xl2">
-                                <table class="bordered">
-                                </table>
+                            <div class="col s12 m12 l8 offset-l2">
+                                ${locale.getString("migration.settings.description")}
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">public</i>
+                                <input id="migration-hostname" type="text" name="hostname" <@validation.validation "hostname"/> value="<#if migrationSettings.hostname()??>${migrationSettings.hostname()}</#if>" placeholder="localhost">
+                                <label for="migration-hostname">${locale.getString("migration.settings.hostname")}</label>
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">dns</i>
+                                <input id="migration-port" type="text" name="port" <@validation.validation "port"/> value="<#if migrationSettings.port()??>${migrationSettings.port()?c}</#if>" placeholder="5432">
+                                <label for="migration-port">${locale.getString("migration.settings.port")}</label>
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">inventory</i>
+                                <input id="migration-database-name" type="text" name="port" <@validation.validation "databaseName"/> value="<#if migrationSettings.databaseName()??>${migrationSettings.databaseName()}</#if>">
+                                <label for="migration-database-name">${locale.getString("migration.settings.databaseName")}</label>
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">person</i>
+                                <input id="migration-username" type="text" name="port" <@validation.validation "username"/> value="<#if migrationSettings.username()??>${migrationSettings.username()}</#if>">
+                                <label for="migration-username">${locale.getString("migration.settings.username")}</label>
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">vpn_key</i>
+                                <input id="migration-password" type="text" name="port" <@validation.validation "password"/> value="<#if migrationSettings.password()??>${migrationSettings.password()}</#if>">
+                                <label for="migration-password">${locale.getString("migration.settings.password")}</label>
+                            </div>
+                        </div>
+
+                        <div class="row">
+                            <div class="input-field col s12 m12 l8 offset-l2">
+                                <i class="material-icons prefix">vpn_key</i>
+                                <input id="migration-verification-password" type="password" name="verificationPassword" <@validation.validation "verificationPassword"/> value="">
+                                <label for="migration-verification-password">${locale.getString("migration.settings.verification.password")}</label>
                             </div>
                         </div>