2

Somewhat a year ago, I came up with the idea of extending my Docker knowledge to begin with creating a sort of multi-platform server image for development purposes, since then, I figured out how to get Nginx and PHP-fpm running in a stable environment. This all is based on a Debian image. Now since a couple one week ago, I wanted to add MySQL functionality to the image. At first, I tried the normal MySQL(-server) image and after trying to fix errors about why it couldn't run in my image, I switched to using MariaDB - I even had changed the Docker image of MySQL to fit to my needs (Replaced CMD ["mysqld"] for a supervisord.conf executable since my project is using several services of course). Now, I'm trying to figure it out for days but it is still not running. At the moment, I've chosen to use https://hub.docker.com/_/mariadb (second: 10.4.12-bionic, 10.4-bionic, 10-bionic, bionic, 10.4.12, 10.4, 10, latest) with my image.

I've just created a mariadb copy on time of writing, but replaced directly executing mysqld (working). When this topic is created, it didn't worked with a supervisord and that works as supposed to be now.

I have a docker-compose.yml where it will be started, here the code:

version: "3"
services:
  db:
    container_name: mariadb
    image: mariadb
    build: .
    restart: on-failure
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=test123
    networks: 
      - local-network

networks:
  local-network:
    driver: bridge

Then, I will execute docker-compose up -d or with the (--build) parameter.

The Dockerfile behind that is:

FROM debian:buster-slim

ENV DEBIAN_FRONTEND noninteractive

ENV GOSU_VERSION 1.12

ENV MARIADB_VERSION 10.4

ENV GPG_KEYS \
    199369E5404BD5FC7D2FE43BCBCB082A1BB943DB \
    177F4010FE56CA3336300305F1656F24C74CD1D8

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN apt-get update && apt-get install --no-install-recommends --no-install-suggests -q -y \
    wget \
    ca-certificates \
    gnupg \
    gnupg1 \
    gnupg2 \
    dirmngr \
    pwgen \
    tzdata \
    xz-utils

# Get Gosu for easy stepdown from root (to avoid sudo/su miscommunications)
# https://github.com/tianon/gosu/releases
RUN set -eux; \
    savedAptMark="$(apt-mark showmanual)"; \
    dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
    wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
    wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
    export GNUPGHOME="$(mktemp -d)"; \
    gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
    gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
    gpgconf --kill all; \
    rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
    apt-mark auto '.*' > /dev/null; \
    [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
    apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
    chmod +x /usr/local/bin/gosu; \
    gosu --version; \
    gosu nobody true

RUN mkdir /docker-entrypoint-initdb.d

RUN set -ex; \
    export GNUPGHOME="$(mktemp -d)"; \
    for key in $GPG_KEYS; do \
        gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
    done; \
    gpg --batch --export $GPG_KEYS > /etc/apt/trusted.gpg.d/mariadb.gpg; \
    command -v gpgconf > /dev/null && gpgconf --kill all || :; \
    rm -r "$GNUPGHOME"; \
    apt-key list

# Add MariaDB repo
RUN set -e;\
    echo "deb http://downloads.mariadb.com/MariaDB/mariadb-$MARIADB_VERSION/repo/debian buster main" > /etc/apt/sources.list.d/mariadb.list; \
    { \
        echo 'Package: *'; \
        echo 'Pin: release o=MariaDB'; \
        echo 'Pin-Priority: 999'; \
    } > /etc/apt/preferences.d/mariadb

# Install MariaDB and set custom requirements
RUN set -ex; \
    { \
        echo "mariadb-server" mysql-server/root_password password 'unused'; \
        echo "mariadb-server" mysql-server/root_password_again password 'unused'; \
    } | debconf-set-selections; \
    apt-get update && apt-get install --no-install-recommends --no-install-suggests -y -q \
    mariadb-server \
    mariadb-backup \
    socat; \
# comment out any "user" entires in the MySQL config ("docker-entrypoint.sh" or "--user" will handle user switching)
    sed -ri 's/^user\s/#&/' /etc/mysql/my.cnf /etc/mysql/conf.d/*; \
# making sure that the correct permissions are set
    mkdir -p /var/lib/mysql /var/run/mysqld; \
    chown -R mysql:mysql /var/lib/mysql /var/run/mysqld; \
# comment out a few problematic configuration values
    find /etc/mysql/ -name '*.cnf' -print0 \
        | xargs -0 grep -lZE '^(bind-address|log)' \
        | xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/'; \
# don't reverse lookup hostnames, they are usually another container
    echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf

# Setup the Supervisor
RUN apt-get update && apt-get install supervisor -y \
    && mkdir -p /var/log/supervisor

COPY /supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN chmod +x /etc/supervisor/conf.d/supervisord.conf

VOLUME /var/lib/mysql

COPY /docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh \
    && ln -s /usr/local/bin/docker-entrypoint.sh /

ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306 33060

# call and execute the supervisor after build
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

After a couple days of working on fixing the image I thought that the supervisord was the issue, it couldn't run because of that or something. Well, here is the supervisord:

[supervisord]
logfile=/var/log/supervisord.log
nodaemon=true
user=root

[program:mysql]
command=/usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql
process_name=mysqld
priority=1
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_events_enabled=true
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stderr_events_enabled=true
autorestart=true
user=mysql

What happens next when the image has been build is that mysql will be executed by the supervisor. But, the problem is that I wanted to use the entrypoint from https://github.com/mariadb-corporation/mariadb-server-docker/tree/master/10.4 - I'm not very well known in Bash, so it will take some time to practice things there. Anyway, the docker-entrypoint has not been executed the first time, the database will not be initialized. What I can do, is creating an own shell script to initialize it. Tested that and it worked, but why can't I just use the default entrypoint as the first choise?

Is it going wrong at some point between Supervisord commands - docker-entrypoint with mysql connection points or something?

I really hope that someone can help me out.

Edit [04/26/2020]: Described the latest situation from now on, database not initializing, no message, notes or warnings from the entrypoint script.

Regards, Colin

3 Answers 3

3

The MySQL service should run as root user, but later that's the mysql user whiche tries to access to the "socket". So, the socket directory should be accessible by mysql user but Superviser runs the mysql service as root user.

I fixed this issue by creating and gave right permission to the MySQL socket directory in my Dockerfile:

ARG MARIADB_MYSQL_SOCKET_DIRECTORY='/var/run/mysqld'

RUN mkdir -p $MARIADB_MYSQL_SOCKET_DIRECTORY && \
    chown root:mysql $MARIADB_MYSQL_SOCKET_DIRECTORY && \
    chmod 774 $MARIADB_MYSQL_SOCKET_DIRECTORY

then configured the Supervisor like this:

[program:mariadb]
command=/usr/sbin/mysqld
autorestart=true
user=root
Sign up to request clarification or add additional context in comments.

Comments

1

This worked the best for me....

FROM mariadb:10.6
RUN apt-get update && apt-get install supervisor -y

So the "stock" mariadb docker container contains a file called docker-entrypoint.sh which can initialize an empty database and users etc, so I prefer that over running mariadbd/mysqld directly.

[program:mariadb]
command=/usr/local/bin/docker-entrypoint.sh mariadbd
autorestart=true
user=mysql
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0

Comments

0

You should be able to chown the socket to the mysql userid.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.