这是我的Dockerfile:
FROM debian:jessie-backports
RUN apt-get update --yes && apt-get upgrade --yes
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git \
curl \
build-essential\
libssl-dev\
ca-certificates\
mysql-server\
redis-server\
elasticsearch
USER root
ENV HOME /root
# MYSQL SETUP
RUN sed -i -e"s/^bind-address\s*=\s*127.0.0.1/#bind-address = 0.0.0.0/" /etc/mysql/my.cnf
RUN sed -i -e"s/^#max_connections\s*=\s*100/max_connections = 200/" /etc/mysql/my.cnf
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
VOLUME ["/var/lib/mysql", "/var/log/mysql"]
EXPOSE 3306
# REDIS SETUP
RUN echo "daemonize yes\nbind 0.0.0.0" >> /etc/redis/redis-serve.conf
RUN sed 's/^daemonize no/daemonize yes/' -i /etc/redis/redis.conf \
&& sed 's/^bind 127.0.0.1/bind 0.0.0.0/' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocket /unixsocket /' -i /etc/redis/redis.conf \
&& sed 's/^# unixsocketperm 755/unixsocketperm 777/' -i /etc/redis/redis.conf \
&& sed '/^logfile/d' -i /etc/redis/redis.conf
VOLUME ["/var/lib/redis", "/var/log/redis"]
EXPOSE 6379 6380
# ELASTICSEARCH SETUP
RUN sed 's/^#START_DAEMON=true/START_DAEMON=true/' -i /etc/default/elasticsearch
VOLUME ["/opt/elasticsearch/data", "/opt/elasticsearch/logs"]
EXPOSE 9200 9300
ADD docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
入口点:
#!/bin/bash
/etc/init.d/mysql start
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
我正在运行的命令启动容器:
docker run -i -t -p 3306:3306 -p 6379:6379 -p 9200:9200 -p 9300:9300 assethost
我想从主机连接到容器中运行的MySQL服务器,但是当我尝试连接时会发生这种情况:
ERROR 1130 (HY000): Host '192.168.99.1' is not allowed to connect to this MySQL server
Redis和Elasticsearch都暴露自己很好。如果我从运行容器时从入口点出来的Bash shell手动重启它,MySQL才会开始接受外部主机。我必须运行/etc/init.d/mysql restart
。只有这样,我才能使用MySQL客户端从主机成功连接。
请注意,我使用的是 docker-machine ,因此我必须为MySQL客户端提供主机IP才能连接。
如何在不必手动重启MySQL的情况下从主机连接到容器中运行的MySQL实例?
Docker版本1.12.1,版本23cf638
答案 0 :(得分:2)
我想出了一种方法,可以在启动时应用skip-grant-tables选项。
在docker-entrypoint.sh中,我改变了
/etc/init.d/mysql start
到
HOME=/etc/mysql /usr/bin/mysqld_safe > /dev/null 2>&1 &
由于my.cnf中已经有[mysqld]
部分,我在Dockerfile中更改了以下行
RUN echo "\n[mysqld]\nskip-grant-tables\n" >> /etc/mysql/my.cnf
到
RUN sed -i '/\[mysqld\]/ a skip-grant-tables\nskip-name-resolve' /etc/mysql/my.cnf
我添加了skip-name-resolve
,因此mysql不会尝试解析本地IP地址的名称。
执行/etc/init.d/mysql restart
时,解决方法不再有效,但/etc/init.d/mysql stop; /etc/init.d/mysql start
保留了'skip-grant-tables'选项。
答案 1 :(得分:0)
我猜测安装完成后MySQL已经启动并且运行sed
更改配置将不会生效。您拥有的入口点有mysql start
,但可能看到MySQL已在运行且没有做任何事情。尝试将该命令更改为mysql restart
,以便您的入口点bash脚本变为:
#!/bin/bash
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
答案 2 :(得分:0)
您正在使用skip-grant-tables标志登录而无需密码。我认为由于/etc/init.d/mysql
脚本的某些原因,第一次启动时会忽略该标志,使root@192.168.99.1
的连接被拒绝。我相信Docker与此问题无关。
要回答您的问题您不必手动重启,您可以将输入点更改为:
#!/bin/bash
/etc/init.d/mysql start
# Wait for mysql to be fully up, then restart (e.g., 5 seconds)
sleep 5
/etc/init.d/mysql restart
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
或者,请勿使用/etc/init.d/mysql start
,而是直接调用mysqld
#!/bin/bash
mysqld &
/etc/init.d/redis-server start
/etc/init.d/elasticsearch start
/bin/bash
此外,虽然在my.cnf中再创建一个[mysqld]
组不是问题,但您应该将新配置添加到现有组:
RUN sed -i '/\[mysqld\]/a skip-grant-tables' /etc/mysql/my.cnf
有关启动/停止Mysql服务器的几种方法,请参阅the doc