Skip to main content
The following guide deploys the Minimus MySQL image together with custom certificates generated with OpenSSL to help you get started. Run the code to try it for yourself.

Components

  • MySQL image: MySQL container configured with --require_secure_transport=ON for client authentication.
  • Dynamic certificate generation via OpenSSL:
    • certgen.sh script: Generates a custom CA, server, and client certificates using OpenSSL.
    • minidebug image: A Minimus dev toolkit that provides a shell, OpenSSL, and other utilities used to generate the certificates.

What this guide demonstrates

  • TLS handshake validation
  • Server/client certificate trust
  • Basic auth and MySQL operations
  • Image compatibility

Directory Structure

.
├── certgen.sh             # Certificate generation script
├── create-certs.yml       # Compose file to run certgen container
└── docker-compose.yml     # Compose file to run MySQLDB

Deploy MySQL with TLS certificates

1

Save certgen.sh

Save the following script to a file named certgen.sh. The script is used to generate the TLS certificates and store them in a certs folder on the host. It sets UID 1000 as the owner of the certificate files to match the default user of the MariaDB process inside the container.
certgen.sh
#!/bin/sh
# Company: Minimus

set -e
cd /certs

echo "[INFO] Generating OpenSSL config..."
cat > openssl.cnf <<EOF
[req]
distinguished_name = req_distinguished_name
prompt = no

[req_distinguished_name]
CN = mysql

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[v3_client]
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
subjectAltName = @alt_names

[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, keyCertSign, cRLSign

[alt_names]
DNS.1 = mysql
DNS.2 = localhost
IP.1 = 172.0.0.1
IP.2 = 192.168.40.0
IP.3 = 192.168.40.2
IP.4 = 192.168.40.3

EOF

echo "[INFO] Creating CA certificate..."
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -sha256 -days 365 \
  -out ca.pem -subj "/CN=MySQL Test CA" \
  -extensions v3_ca -config openssl.cnf

echo "[INFO] Creating server certificate..."
openssl genrsa -out server-key.pem 2048
openssl req -new -key server-key.pem -out server.csr \
  -config openssl.cnf -extensions v3_req
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
  -out server-cert.pem -days 365 -sha256 \
  -extfile openssl.cnf -extensions v3_req

echo "[INFO] Creating client certificate..."
openssl genrsa -out client-key.pem 2048
openssl req -new -key client-key.pem -out client.csr -subj "/CN=root"
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
  -out client-cert.pem -days 365 -sha256 \
  -extfile openssl.cnf -extensions v3_client

# Permissions
chmod 644 *.pem
chown -R 1000:1000 /certs/*.pem || echo "[WARN] chown failed (non-root?)"

echo "[SUCCESS] Certificates generated for MySQL."
2

Save create-certs.yml

Save the following YAML file to run with Docker Compose. It uses the Minimus minidebug image to generate the certificates with the certgen.shshell script. Minidebug is a Minimus dev toolkit that provides a shell, OpenSSL, and other utilities.The certificates will be persisted in the certs volume on the host.
create-certs.yml
services:
  certgen:
    image: reg.mini.dev/minidebug:latest
    container_name: MySQL_certgen
    volumes:
    - ./certs:/certs
    - ./certgen.sh:/certgen.sh:ro
    entrypoint:
    - /bin/sh
    - /certgen.sh
    network_mode: none
3

Generate certificates

Run the following to generate the certificates:
docker compose -f create-certs.yml up

TLS certificates

The script certgen.sh generates the following self-signed certificates:
  • Self-signed CA certificate (ca.pem )
  • Server certificates (server-cert.pem, server-key.pem, server.csr )
  • Client certificates for testuser (client.csr , client.pem, client-cert.pem ,client-key.pem)
Certificate permissions are adjusted to support non-root containers. We will mount thses certificates into the MySQL container.
4

Save Docker Compose script

Save the following Docker Compose script to a file named docker-compose.yml. This script sets up the MySQL service with a healthcheck, mounts a volume with the certificates, maps port 3306, and connects the container to a custom network:
docker-compose.yml
services:
  mysql:
    image: reg.mini.dev/mysql:latest
    container_name: mysql-1
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: testdb
      MYSQL_USER: testuser
      MYSQL_PASSWORD: testpass
    volumes:
      - ./certs:/certs:ro
    ports:
    - 3306:3306
    healthcheck:
      test:
      - CMD
      - mysqladmin
      - ping
      - -ptestpass
      interval: 5s
      retries: 10
    command:
    - --ssl-ca=/certs/ca.pem
    - --ssl-cert=/certs/server-cert.pem
    - --ssl-key=/certs/server-key.pem
    - --require_secure_transport=ON
    - --skip-name-resolve
5

Run MySQL

Start the MySQL container:
docker compose -f docker-compose.yml up -d
6

Run tests

Following are a few commands you can try out:
  1. Connect to the database:
    mysql -h 127.0.0.1 -P 3306 -u root -p \
      --ssl \
      --ssl-ca=./certs/ca.pem \
      --ssl-cert=./certs/client-cert.pem \
      --ssl-key=./certs/client-key.pem
    
    You should get a response from the server asking to input the password. If you used the compose file from this guide as is, the password is rootpass.
  2. Create a test database (for example my_new_db):
    CREATE DATABASE my_new_db; 
    
  3. List all databases:
    SHOW DATABASES;
    
  4. Show server version:
    SELECT version();
    
  5. Check that TLS is active:
    SHOW VARIABLES LIKE 'tls_version';
    SHOW STATUS LIKE 'Ssl_version';
    SHOW STATUS LIKE 'Ssl_cipher';
    SHOW VARIABLES LIKE 'ssl_%';
    
    Some server options and system variables were recently deprecated, including --ssl, --skip-ssl, and --admin-ssl server options, and the have_ssl and have_openssl system variables. Learn more