MariaDB 服务器在 Docker 容器中无法停止。

huangapple go评论120阅读模式
英文:

MariaDB server failing to stop in Docker container

问题

I am trying to create a Docker container for MariaDB server using Debian as the base image. My Dockerfile is as follows:

FROM debian:buster

RUN apt-get update -y && apt-get upgrade -y && apt-get install wget mariadb-server procps -y
COPY ./tools/init.sh /tmp/init.sh
RUN chmod +x /tmp/init.sh 
EXPOSE 3306
RUN sed -i 's/^bind-address\s*=.*/bind-address=0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
ENTRYPOINT [ "sh", "/tmp/init.sh" ]
CMD [ "mysqld_safe" , "--verbose"]

for now I just want to get it to work so my init.sh script is simply:

service mysql start && service mysql stop

However, I'm getting an error of:

db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1

it seems that the database is started successfully while the second line suggests that I am trying to use the root user without a password, but I read that by default, the root password is blank, and I'm not setting it or using MySQL client anywhere, so I frankly have no idea where that is coming from. The third line shows that the MariaDB server is failing to stop, which I also have no idea why.

what i have tried to troubleshoot the problem:

  1. I manually docker run --rm -it --name testing_db debian and run all the instructions from dockerfile inside the container, everything worked fine and was able to start and stop the database server ??
  2. to troubleshoot the problem of access denied I read somewhere to try to reset the root password, so i tried doing so in a RUN instruction in the Dockerfile as
RUN service mysql start &&  mysql -u root -e  "ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD'; FLUSH PRIVILEGES;"

however, that didn't solve the issue.

What are your thoughts on this?

英文:

I am trying to create a Docker container for MariaDB server using Debian as the base image. My Dockerfile is as follows:

FROM debian:buster

RUN apt-get update -y && apt-get upgrade -y && apt-get install wget mariadb-server procps -y
COPY ./tools/init.sh /tmp/init.sh
RUN chmod +x /tmp/init.sh 
EXPOSE 3306
RUN sed -i 's/^bind-address\s*=.*/bind-address=0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
ENTRYPOINT [ "sh", "/tmp/init.sh" ]
CMD [ "mysqld_safe" , "--verbose"]

for now I just want to get it to work so my init.sh script is simply:

service mysql start && service mysql stop

However, I'm getting a error of:

db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1
db             | Starting MariaDB database server: mysqld.
db             | ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
db             | Stopping MariaDB database server: mysqld failed!
db exited with code 1

it seems that the database is started successfully while the second line suggests that I am trying to use the root user without a password, but I read that by default, the root password is blank, and I'm not setting it or using MySQL client anywhere, so I frankly have no idea where that is coming from. The third line shows that the MariaDB server is failing to stop, which I also have no idea why.

what i have tried to troubleshoot the problem:

  1. I manually docker run --rm -it --name testing_db debian and run all the instructions from dockerfile inside the container, everything worked fine and was able to start and stop the database server ??
  2. to troubleshoot the problem of access denied I read somewhere to try to reset the root password, so i tried doing so in a RUN instruction in the Dockerfile as

    RUN service mysql start && mysql -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD'; FLUSH PRIVILEGES;"

    however, that didn't solve the issue.

What are your thoughts in this.

答案1

得分: 1

I'm guessing this will work if you delete the ENTRYPOINT line and the init.sh script.

A Docker container only runs one command. That command is constructed by passing the CMD as arguments to the ENTRYPOINT. When the ENTRYPOINT process exits, the container exits too.

In your case the init.sh just runs two service commands and exits. service broadly doesn't work in Docker, though. One of the ways it can fail is that the service command launches the service in the background, so if your container's main process is just to run service mysql start, when that command completes the container exits too.

The right answer here is to not use service but rather to just run the main container process in the foreground. You already have that as your CMD, though, you're just not running it. This is where, if you delete the ENTRYPOINT, then CMD alone will be the main container process.

If you do need to keep the ENTRYPOINT, then you need to make sure it runs the CMD when it's done with its initial setup. The standard way to do this is to end the script with exec "$@"

#!/bin/sh
# init.sh

# ... do startup-time setup ...

# run the main CMD
exec "$@"

This approach can be useful for setting environment variables, copying files around, rendering injected templated configuration files, and some other simple startup-time tasks.

Getting this to actually initialize a database is tricky. The standard mariadb image has an involved entrypoint script that starts a database as a background process (without using service) and without a network listener, then running the /docker-entrypoint-initdb.d scripts, then killing the local-only database and starting the real one.

英文:

I'm guessing this will work if you delete the ENTRYPOINT line and the init.sh script.

A Docker container only runs one command. That command is constructed by passing the CMD as arguments to the ENTRYPOINT. When the ENTRYPOINT process exits, the container exits too.

In your case the init.sh just runs two service commands and exits. service broadly doesn't work in Docker, though. One of the ways it can fail is that the service command launches the service in the background, so if your container's main process is just to run service mysql start, when that command completes the container exits too.

The right answer here is to not use service but rather to just run the main container process in the foreground. You already have that as your CMD, though, you're just not running it. This is where, if you delete the ENTRYPOINT, then CMD alone will be the main container process.


If you do need to keep the ENTRYPOINT, then you need to make sure it runs the CMD when it's done with its initial setup. The standard way to do this is to end the script with exec "$@"

#!/bin/sh
# init.sh

# ... do startup-time setup ...

# run the main CMD
exec "$@"

This approach can be useful for setting environment variables, copying files around, rendering injected templated configuration files, and some other simple startup-time tasks.

Getting this to actually initialize a database is tricky. The standard mariadb image has an involved entrypoint script that starts a database as a background process (without using service) and without a network listener, then running the /docker-entrypoint-initdb.d scripts, then killing the local-only database and starting the real one.

huangapple
  • 本文由 发表于 2023年3月9日 18:41:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定