I have several applications that I’ve been running that use the same pattern.
Some REST, or www app with a database to support it. So the docker-compose would look something like this.
www:
build:
context: .
dockerfile: compose/app/Dockerfile
env_file: .env
restart: always
ports:
- "9000:9000"
db:
image: mysql:5.7.29
restart: always
env_file: .env
healthcheck:
test: ["CMD-SHELL", 'mysql --database=$$MYSQL_DATABASE --password=$$MYSQL_ROOT_PASSWORD --execute="SELECT 1 + 1" --skip-column-names -B']
interval: 10s
timeout: 5s
retries: 5
This works fine for a single instance but once you have 2 or 3 mysql instances this gets a bit heavy for the server. Not to mention just straight out dumb to have 3 DB servers because i need 3 databases.
Solution:
- Set up a shared DB resource.
version: '3.7'
services:
shared_mysql:
container_name: shared_mysql
image: mysql:5.7.29
command: --default-authentication-plugin=mysql_native_password
restart: always
env_file: .env
networks:
- shared_backend
volumes:
- ./data:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", 'mysql --database=$$MYSQL_DATABASE --password=$$MYSQL_ROOT_PASSWORD --execute="SELECT 1 + 1" --skip-column-names -B']
interval: 10s
timeout: 5s
retries: 5
networks:
shared_backend:
name: shared_backend
# use a custom driver, with no options
driver: bridge
the .env defines only the root password.
sql/site.sql
will define a new database and user with all privileges on the specific database.
Please note the network name is important as well as the container_name.
Now to update the existing app to use this, our new app will instead look like this:
version: '3.7'
services:
www:
build:
context: .
dockerfile: compose/app/Dockerfile
volumes:
- ./storage/app/public:/app/public/storage
env_file: .env
networks:
- shared_backend
ports:
- "9000:9000"
external_links:
- shared_mysql
networks:
shared_backend:
name: shared_backend
external: true
At this point we simply need to update any reference to the database host to be shared_backend.
NOTE. This is definitely starting to push what docker compose was designed for. Using kubernetes would be a better pattern but till then. This isn’t a bad compromise.
TODO: add systemd startup scripts.