When there are multiple apps on a server using same database, e.g. postgres, there are several deployment options:
- Each app can have a database container for each own
- There could be a single database container and a shared network for all apps
- using a single docker-compose.yml for all apps having one database container,
- database can be installed on local host with different users for each apps
When using single DB, i.e. options 2-4, you have to decied for using same creditentials for all apps, or make DB users per apps. The former requires less work but may cause interference and debug can be more complicated, the latter is easier to implement but less error prune. I suggest to have shared user for every type of apps. If you have 5 instances of app A with different databases, and 3 instances of app B, you can make 2 shared users for each. Of course shared database means you have to know how your apps interact with database and you are resposible to be sure they would not overwrite eachother's data. Also, if your app can have multiple databases, it is better to have separate users for apps, but if they soley work with one database, shared user is the one to go for, specially if apps does not create new database or the don't try to drop existing databases and create new ones.
Which one should be used? Well as you might already know, there is not a simple yes/no answer too this question. It depends on many parameters, such as:
- Do all apps use the same database version? Is it going to be so for forseenable future?
- Do you have to do manual jobs on databases for each app? e.g. manual backup?
- Could there be a need to have different database configuration for each app?
- Is it possible for apps to interfere in each other data accidentaly?
- Are the apps similar? say you have 30 instanses of the same app with different databases for different clients.
- How much resources do you have in hand? Are resources critical?
- ...
Well, we always need to compare pros and cons and hope that our decision won't mess up everything in the future. In the table below I have choosed some criteria that might be helping.
DB per stack | Shared Docker Network | All-in-one docker-compose.yml | Local DB | |
---|---|---|---|---|
Data integrity | Feel safe, everything is separated | Apps should have different DB names | Apps should have different DB names | Apps should have different DB names |
Backups and tunes | Manual backup is a hell | Just one DB to backup | Just one DB to backup | Just one DB to backup |
Compatibilty | No issues here | All apps should be able to run on same DB version | All apps should be able to run on same DB version | All apps should be able to run on same DB version |
Implementation | Easy, nothing special | Set external network in every docker-compose.yml | docker-compose.yml could get very complicated and bulky | Giving access to the local host is not straight forward |
Edits required | Just run stacks | Add one line to individual docker-compose.yml | Combine all individual docker-compose.yml, not straight forward, you cannot just install apps | docker-compose.yml for each app should be edited to remove the DB container and mend manually to add local host IP |
Resources | A lot, many DB containers | A little, one DB container | A little, one DB container | A little less, no DB container |
If you have enough resources and apps can manage their own backups and manual operations, go for option 1. Option 2 is a little more complicated but if there are not many apps or the apps are similar this is a good one. Option 3 is a little more complicated and you have to edit a main docker-compose.yml, if there are not many apps or the apps are similar this is a good one. If each app currently has different repository with docker-compose.yml in, you have to move it out, it can get cumbersum. Options 4 is not recommended unless you have a running local database and a few apps and you are very low on resources.