Docker Compose and MariaDB: Fix missing configuration
Tags: docker, dockercompose, mariadb, troubleshooting
Published: 2021-01-16 14:07:35

\* The cover image is originally by [wallace769](https://pixabay.com/users/wallace769-5217358) and edited with great appreciation.

---

Today I tried to create [Mariadb](https://mariadb.org/) server for app development with [Docker](https://www.docker.com/) and [Docker Compose](https://docs.docker.com/compose).
Here is my primary `docker-compose.yml` 😃 :

```yaml
# docker-compose.yml
version: "3"
services:
    db:
        container_name: "${APP_NAME}-mariadb"
        image: mariadb/server:10.5
        restart: always
        environment:
            MARIADB_ROOT_PASSWORD: "test"
        networks:
            app_net:
                ipv4_address: "192.168.1.10"
        ports:
            - "3306:3306"
        volumes:
            - db_data:/var/lib/mysql
            - db_conf:/etc/mysql
networks:
    app_net:
        ipam:
            config:
                - subnet: 192.168.1.0/24
volumes:
    db_data:
    db_conf:
```

Besides, I forgot why I needed `db_conf` volume...

I built the container and ran the server via command line:

```console
$ docker-compose build
$ docker-compose up -d
```

The test after it was successful. I could connect to the database server, whose ip:port was "192.168.1.10:3306", username was "root" and password was "test".

Then I changed the yaml file as below for the configuration to be defined outside due to dev env.

```diff
-             MARIADB_ROOT_PASSWORD: "test"
+             MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}"
```

`.env` file was created in the current directory at the same time where `MARIADB_ROOT_PASSWORD` was defined:

```ini
# .env
MARIADB_ROOT_PASSWORD=dev
```

The test was sucessful again. I could connect to the server with password "dev". The goal seemed nearby 😆
...and actually was not 😗

The trouble happened when I redefined MARIADB_ROOT_PASSWORD as "dev2!" instead of "dev".
The update was never applied. I couldn't connect to the server with the new password. (Well, the old password must have worked but I was confused far from the idea.)
Error messages returned to mariadb client were like these:

```
Access denied for user 'root'@'192.168.1.1' (using password: YES)
Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding'
```

Charset? I used just alphanumeric and a popular symbol. I was by far confused.

The answer was [Docker volume](https://docs.docker.com/storage/volumes). I stored MariaDB configuration as

```yaml
services:
    db:
        # ...
        volumes:
            # ...
            - db_conf:/etc/mysql
        # ...
volumes:
    # ...
    db_conf:
```

in the yaml file. The volume was split from the very container as well as networks, which was not removed when the container it belonged to was recreated. Therefore, the database configuration was not changed.

What I had to do was to remove container first and then do volume:

```console
$ docker container ls -a
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS                           PORTS     NAMES
...
container_id   container_image   "/bin/sh -c '..."   xx minutes ago      Created (x) xx minutes ago                  container_names
$ docker container rm container_id

$ docker volume ls
DRIVER    VOLUME NAME
...
local     dev_db_conf
$ docker volume rm dev_db_conf
```

That was it. I recreated the container. Then my trial to connect with new password was happily successful 😄

The below is my latest `docker-compose.yml` and `.env` to edit not only MariaDB root password but also database name and username/password:

```yaml
# docker-compose.yml
version: "3"
services:
    db:
        container_name: "${APP_NAME}-mariadb"
        image: mariadb/server:10.5
        restart: always
        # be sure to run `docker volume rm dev_dev_conf` when changing envs
        environment:
            MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}"
            MARIADB_DATABASE: "${MARIADB_DATABASE}"
            MARIADB_USER: "${MARIADB_USER}"
            MARIADB_PASSWORD: "${MARIADB_PASSWORD}"
        networks:
            app_net:
                ipv4_address: "192.168.1.10"
        ports:
            - "3306:3306"
        volumes:
            - db_data:/var/lib/mysql
            - db_conf:/etc/mysql
networks:
    app_net:
        ipam:
            config:
                - subnet: 192.168.1.0/24
volumes:
    db_data:
    db_conf:
```

```ini
# .env
MARIADB_DATABASE=dev
MARIADB_USER=dev
MARIADB_PASSWORD=dev
MARIADB_ROOT_PASSWORD=dev
```