Docker and .NET migrations
Hello everyone,
I created a Dockerfile for each of my APIs (using .NET 9) and a Docker Compose file to containerize all my applications. I've done some research, but I have a few questions:
In a microservices architecture, should each service have its own database?
(e.g., Auth.API => PostgreSQL and Story.API => MongoDB)
Also, I can't apply the EF migrations once my Auth service is running in its container. I checked this link: https://www.reddit.com/r/csharp/comments/1h3kt2r/aspnet_8_and_docker/
I understand the theory of adding a separate Dockerfile just to apply the migration once the API and the database are up and running in the container, but I can't figure out how to implement it. Do you have any advice or ideas?
Thanks in advance for your help!
4 Replies
In my opinion, each service needs to have its own data 'silo'. Generally this would manifest as separate physical databases, but you could also get away with having different schemas inside one database. The main point is that each service can stand apart from the others, including the data they need. If two services hit the same table, they're conjoined. Each service doesn't need to use a different DB type, i.e. they can both use postgres if that's what you prefer.
Regarding migrations, my understanding of the best practice is that you don't automatically run them on startup. Instead you get the relevant SQL from EF Core and then run it in yourself in an ad-hoc manner for more control. That in turn means no extra container needed.
Applying Migrations - EF Core
Strategies for applying schema migrations to production and development databases using Entity Framework Core
If I wanted to automate that, I would personally reach for a dedicated deployment tool like Octopus (or some github action/devops pipeline thing), not docker. Though I'm sure plenty of people do it the way you've referenced and it works well for them
@Becquerel First of all, thank you very much for your quick response.
If I understand correctly, I am not required to create a separate database for each service. However, services should avoid accessing the same table in the database. You mentioned schemas, but I must admit I don’t know much about them. Could you provide an example or a link to help me understand this better?
As for my approach, I was planning to have each service define its own entities and work only with the data it needs and has defined (using EF migrations). If a service requires additional data, it should call another service.
Regarding the second point, I understand a bit better now: I can generate an SQL script from the EF migration to insert tables directly into the database (without going through the service inside the container?). My issue is that I want to be able to test my container locally with my services as if I were in production (so without relying on a CI/CD pipeline with Git).