Using a database defined in external compose file

Thanks @meyay.

For future reference for anyone who is looking for something similar this is what I ended up with.

Defining a shared DB connection. I threw a PSQL one in there as well if anyone uses that over mysql

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:
        - ./mysql_data:/var/lib/mysql
        - ./mysql_init:/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

  shared_psql:
    image: postgres:12
    container_name: shared_psql
    volumes:
      - ./psql_data:/var/lib/postgresql/data
      - ./psql_init:/docker-entrypoint-initdb.d
    restart: always
    env_file: .env
    networks:
       - shared_backend

networks:
    shared_backend:
        name: shared_backend
        # use a custom driver, with no options
        driver: bridge

My actual app then looks like this:

version: '3.7'
services:
  podcast_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


Like it was mentioned there is no bootstrapping of the database once data exists. So you’ll have to create a new user manually. I keep the init scripts in the respective directories even if they’re not being executed automatically.

MySQL

CREATE DATABASE podcast;
CREATE USER 'podcast_user'@'%' IDENTIFIED BY 'Secret';
GRANT ALL PRIVILEGES ON podcast.* TO 'podcast_user'@'%';

PSQL:

CREATE DATABASE podcast;
CREATE USER podcast_user WITH encrypted password 'Secret';
GRANT ALL privileges ON DATABASE podcast TO podcast_user;

also,

shared_docker.service:

[Unit]
Description = Shared DB
After=docker.service
Requires=docker.service

[Service]
Type=simple
WorkingDirectory=/home/docker_user/shared
ExecStart=/usr/bin/docker-compose up
ExecStop=/usr/bin/docker-compose  stop
ExecReload =/usr/bin/docker-compose restart
User=docker_user
Group=docker
Restart=always
RestartSec=3


[Install]
WantedBy=multi-user.target

I think this should as well. podcast.service

[Unit]
Description = Podcast Website
After=shared_docker.service
Requires=mysql_docker.service

[Service]
Type=simple
WorkingDirectory=/home/docker_user/podcast
ExecStart=/usr/bin/docker-compose -f production.yml up 
ExecStop=/usr/bin/docker-compose -f production.yml stop
ExecReload =/usr/bin/docker-compose -f production.yml restart
User=docker_user
Group=docker
Restart=always
RestartSec=3


[Install]
WantedBy=multi-user.target

2 Likes