mysql
The default mysql provisioner adds a mysql instance and then ensures that the required databases are created on startup.
Provisions a dedicated MySQL database on a shared instance.
type: mysql
expected_outputs:
- host
- port
- name
- database
- username
- passwordprovisioners.yaml
(view on GitHub)
:
- uri: template://default-provisioners/mysql
# By default, match all mysql types regardless of class and id. If you want to override this, create another
# provisioner definition with a higher priority.
type: mysql
description: Provisions a dedicated MySQL database on a shared instance.
# Init template has the random service name and password if needed later
init: |
randomServiceName: mysql-{{ randAlphaNum 6 }}
randomDatabase: db{{ randAlpha 8 }}
randomUsername: user-{{ randAlpha 8 }}
randomPassword: {{ randAlphaNum 16 | quote }}
randomRootPassword: {{ randAlphaNum 16 | quote }}
sk: default-provisioners-mysql-instance
publishPort: {{ dig "annotations" "compose.score.dev/publish-port" "0" .Metadata | quote }}
# The state for each database resource is a unique db name and credentials
state: |
database: {{ dig "database" .Init.randomDatabase .State | quote }}
username: {{ dig "username" .Init.randomUsername .State | quote }}
password: {{ dig "password" .Init.randomPassword .State | quote }}
# All instances agree on the shared state since there is no concurrency here
shared: |
{{ .Init.sk }}:
instanceServiceName: {{ dig .Init.sk "instanceServiceName" .Init.randomServiceName .Shared | quote }}
instancePassword: {{ dig .Init.sk "instancePassword" .Init.randomPassword .Shared | quote }}
instanceRootPassword: {{ dig .Init.sk "instanceRootPassword" .Init.randomRootPassword .Shared | quote }}
# The outputs are the core database outputs. We output both name and database for broader compatibility.
outputs: |
host: {{ dig .Init.sk "instanceServiceName" "" .Shared }}
port: 3306
name: {{ .State.database }}
database: {{ .State.database }}
username: {{ .State.username }}
password: {{ .State.password }}
# Write out an idempotent create script per database
files: |
{{ dig .Init.sk "instanceServiceName" "" .Shared }}-db-scripts/{{ .State.database }}.sql: |
CREATE DATABASE IF NOT EXISTS {{ .State.database }};
USE {{ .State.database }};
CREATE USER IF NOT EXISTS '{{ .State.username }}'@'localhost' IDENTIFIED BY '{{ .State.password }}';
GRANT ALL PRIVILEGES ON {{ .State.database }} TO '{{ .State.username }}'@'localhost';
FLUSH PRIVILEGES;
# Ensure the data volume exists
volumes: |
{{ dig .Init.sk "instanceServiceName" "" .Shared }}-data:
driver: local
# Create an services with the database itself
services: |
{{ dig .Init.sk "instanceServiceName" "" .Shared }}:
image: mirror.gcr.io/mysql:8
restart: always
environment:
MYSQL_DATABASE: {{ .State.database }}
MYSQL_USER: {{ .State.username }}
MYSQL_PASSWORD: {{ dig .Init.sk "instancePassword" "" .Shared | quote }}
MYSQL_ROOT_PASSWORD: {{ dig .Init.sk "instanceRootPassword" "" .Shared | quote }}
{{ if ne .Init.publishPort "0" }}
ports:
- target: 3306
published: {{ .Init.publishPort }}
{{ end }}
volumes:
- type: bind
source: {{ .MountsDirectory }}/{{ dig .Init.sk "instanceServiceName" "" .Shared }}-db-scripts
target: /docker-entrypoint-initdb.d/
- type: volume
source: {{ dig .Init.sk "instanceServiceName" "" .Shared }}-data
target: /var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p$${MYSQL_ROOT_PASSWORD}"]
interval: 5s
timeout: 3s
retries: 10
info_logs: |
- "{{.Uid}}: To connect to mysql, enter password {{ .State.password | squote }} at: \"docker run -it --network {{ .ComposeProjectName }}_default --rm mysql:8 mysql -h {{ dig .Init.sk "instanceServiceName" "" .Shared }} -u {{ .State.username }} -p\""
{{ if ne .Init.publishPort "0" }}
- "{{.Uid}}: Or connect your mysql client to \"
mysql://{{ .State.username }}:{{ .State.password }}@{{ dig .Init.sk "instanceServiceName" "" .Shared }}:{{ .Init.publishPort }}/{{ .State.database }}\""
{{ end }}
expected_outputs:
- host
- port
- name
- database
- username
- password