Fix prod deploy Flyway validation for removed dev seed migrations.
Backend crashed on startup because the prod DB still records V6 (and possibly V2/V4) from when seeds lived in db/migration, while prod only loads schema migrations. ignore-migration-patterns alone did not prevent validate failure on the runner. - Run Flyway repair before migrate on the prod profile - Add ProdFlywayConfigTest for repair-then-migrate order - Document the V6 error in README deploy troubleshooting
This commit is contained in:
parent
61a7b8a40c
commit
fb9713d8d8
3 changed files with 62 additions and 1 deletions
|
|
@ -317,11 +317,15 @@ If the job passes the frontend check but the backend never becomes healthy:
|
||||||
|
|
||||||
1. Open the failed job log and read **Backend logs** (printed before rollback).
|
1. Open the failed job log and read **Backend logs** (printed before rollback).
|
||||||
2. Match the error to a fix — do not guess:
|
2. Match the error to a fix — do not guess:
|
||||||
|
- **`Detected applied migration not resolved locally: 6`** (or 2, 4) — prod DB still lists
|
||||||
|
dev seed migrations removed from `db/migration`. Fixed in app via `ProdFlywayConfig`
|
||||||
|
(repair before migrate); redeploy after that commit is on `master`.
|
||||||
- **`password authentication failed`** — DB credentials in the running stack do not match
|
- **`password authentication failed`** — DB credentials in the running stack do not match
|
||||||
what Postgres was initialized with; fix credentials or Postgres password to match (only
|
what Postgres was initialized with; fix credentials or Postgres password to match (only
|
||||||
wipe the volume if you accept losing prod data).
|
wipe the volume if you accept losing prod data).
|
||||||
- **`Production requires ADMIN_EMAIL and ADMIN_PASSWORD`** — add those Forgejo secrets.
|
- **`Production requires ADMIN_EMAIL and ADMIN_PASSWORD`** — add those Forgejo secrets.
|
||||||
- **Flyway / migration errors** — fix schema or migration history before redeploying.
|
- **Other Flyway / migration errors** — read the stack trace; do not wipe the volume unless
|
||||||
|
the log clearly requires it.
|
||||||
3. **DBeaver from your laptop** — prod Postgres binds to `127.0.0.1:5433` on the server only.
|
3. **DBeaver from your laptop** — prod Postgres binds to `127.0.0.1:5433` on the server only.
|
||||||
Use an SSH tunnel, then host `localhost` port `5433` (not `192.168.0.59` directly).
|
Use an SSH tunnel, then host `localhost` port `5433` (not `192.168.0.59` directly).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package se.bilhalsning.config;
|
||||||
|
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.springframework.boot.flyway.autoconfigure.FlywayMigrationStrategy;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@Profile("prod")
|
||||||
|
public class ProdFlywayConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prod databases may record dev seed migrations (V2, V4, V6) from before they moved to
|
||||||
|
* db/dev-migration/. Repair marks those missing scripts as deleted so validate passes.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public FlywayMigrationStrategy prodFlywayMigrationStrategy() {
|
||||||
|
return (Flyway flyway) -> {
|
||||||
|
flyway.repair();
|
||||||
|
flyway.migrate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package se.bilhalsning.config;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.inOrder;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.flyway.autoconfigure.FlywayMigrationStrategy;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.mockito.InOrder;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
properties = {
|
||||||
|
"app.admin.email=admin@test.se",
|
||||||
|
"app.admin.password=test-password",
|
||||||
|
})
|
||||||
|
@ActiveProfiles("prod")
|
||||||
|
class ProdFlywayConfigTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FlywayMigrationStrategy flywayMigrationStrategy;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldRepairBeforeMigrateOnProd() {
|
||||||
|
Flyway flyway = mock(Flyway.class);
|
||||||
|
flywayMigrationStrategy.migrate(flyway);
|
||||||
|
InOrder order = inOrder(flyway);
|
||||||
|
order.verify(flyway).repair();
|
||||||
|
order.verify(flyway).migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue