使用docker-compose与docker运行的结果不同

时间:2017-01-12 16:09:16

标签: docker phpmyadmin docker-compose mariadb

我正在设置一个通用的公共数据库,我可以链接到其他容器。使用docker-composedocker run时,我遇到了不同的结果。

搬运工-compose.yml

mysql:
    image: mariadb:10.1
    ports:
        - 3306:3306
    environment:
        MYSQL_ROOT_PASSWORD: root-secret
        MYSQL_USER: dbuser
        MYSQL_PASSWORD: my-secret
    volumes:
        - ./conf:/etc/mysql/conf.d
        - ./data:/var/lib/mysql
        - ./logs:/var/log/mysql
pma:
    image: phpmyadmin/phpmyadmin
    links:
        - mysql:db
    ports:
        - 8088:80
    environment:
        MYSQL_ROOT_PASSWORD: root-secret
        MYSQL_USER: dbuser
        MYSQL_PASSWORD: my-secret

我正在运行的docker命令是:

docker run -d -P --name mysql -v conf:/etc/mysql/conf.d -v data:/var/lib/mysql \
    -v logs:/var/log/mysql -e MYSQL_ROOT_PASSWORD=root-secret \
    -e MYSQL_USER=dbuser -e MYSQL_PASSWORD=my-secret -p 3306:3306 mariadb:10.1
docker run -d --name pma --link mysql:db  -e MYSQL_ROOT_PASSWORD=root-secret \
    -e MYSQL_USER=dbuser -e MYSQL_PASSWORD=my-secret -p 8088:80 phpmyadmin/phpmyadmin

使用docker-compose up -d时,一切正常,主机的数据目录中填充了数据库文件。此外,phpmyadmin能够毫无问题地连接到数据库容器。

使用docker命令时,主机的数据目录保持为空,数据存储在容器中。 phpmyadmin在尝试登录时给了我“访问被拒绝”。

任何人都可以告诉我为什么数据量正确安装并且phpmyadmin能够在使用docker-compose而不是docker时进行通信?

3 个答案:

答案 0 :(得分:2)

使用以下命令:

docker run -d -P --name mysql \
  -v $(pwd)/conf:/etc/mysql/conf.d \
  -v $(pwd)/data:/var/lib/mysql \
  -v $(pwd)/logs:/var/log/mysql \
  -e MYSQL_ROOT_PASSWORD=root-secret \
  -e MYSQL_USER=dbuser \
  -e MYSQL_PASSWORD=my-secret \
  -p 3306:3306 \
  mariadb:10.1 

docker run -d --name pma \
  --link mysql:db  \
  -e MYSQL_ROOT_PASSWORD=root-secret \
  -e MYSQL_USER=dbuser \
  -e MYSQL_PASSWORD=my-secret \
  -p 8088:80 \
  phpmyadmin/phpmyadmin

<强>原因

您没有正确安装卷。在docker-compose.yml文件中,您指定路径,相对于文件所在的目录

volumes:
    - ./conf:/etc/mysql/conf.d
    - ./data:/var/lib/mysql
    - ./logs:/var/log/mysql

但是,在docker run命令中,您没有使用相对路径

-v conf:/etc/mysql/conf.d -v data:/var/lib/mysql -v logs:/var/log/mysql

此外,docker run要求您指定要在容器内安装的本地目录的绝对路径。 因此,使用类似于docker-compose.yml的语法,您必须使用类似pwd的内容来获取绝对路径,或者手动编写路径。

-v /path/to/conf:/etc/mysql/conf.d \
-v /path/to/data:/var/lib/mysql \
-v path/to/logs:/var/log/mysql \

干杯!

答案 1 :(得分:1)

正如其他人所说,不同之处在于您指定音量路径的方式。但到目前为止,没有人解释为什么,即使你在docker run中“错误地”指定了卷,Docker也会毫无错误地接受它们并继续前进,或者为什么你看到了你看到的行为。

搬运工-撰写

在docker-compose.yml中,你使用了这个:

volumes:
  - ./conf:/etc/mysql/conf.d
  - ./data:/var/lib/mysql
  - ./logs:/var/log/mysql

在这种情况下,您将使用前导./获取本地相对路径,并使用绝对路径安装在容器内。这很好用。

docker run

docker run命令中,您使用了这个:

-v conf:/etc/mysql/conf.d -v data:/var/lib/mysql -v logs:/var/log/mysql

很明显,你的意思是“使用相对路径”。正如您已经提到的,如果您在此处指定带有前导./的相对路径,则会出现错误,即您无法执行此操作:

-v ./conf:/etc/mysql/conf.d -v ./data:/var/lib/mysql -v ./logs:/var/log/mysql

发生了什么

您注意到当您通过docker-compose运行时,它可以按预期工作:使用主机安装的卷。但是,当您通过docker run运行时,数据将保留在容器内,而不会使用主机安装的目录。为什么呢?

原因是你使用-v语法有一个有效的目的,它不是你想到的那个。您指定它的方式是,您创建了名为的Docker卷。冒号前的主要部分遵循以下规则:

  1. 如果看到前导./,则为相对目录:错误
  2. 如果看到前导/,则这是绝对路径。将容积装入容器中。
  3. 如果你给出像foo/bar这样的东西,这被认为是一条相对路径。的错误
  4. 最后,如果您指定word:/some/path,则word将被视为名称。使用名称word创建Docker卷,并将其安装在/some/path的容器中。
  5. 因此,在使用docker run时,您创建了卷。这些被用在容器内。卷正在使用中,而不是主机安装卷。

    无法连接错误

    我认为您在网络设置方面没有任何问题。我对你的连接错误的最好猜测是在docker run场景中,你的数据库没有正确设置,因此phpmyadmin无法使用mysql。如果您纠正了音量问题并且phpmyadmin仍然存在问题,请使用您遇到的任何特定错误更新您的问题,并对我的回答发表评论,以便我再次查看。

    参考

    Docker run reference (VOLUME)

      

    -v, - volume = [host-src:] container-dest [:]:绑定一个卷。
      逗号分隔的选项是[rw | ro],[z | Z],
      [[r] shared | [r] slave | [r] private]和[nocopy]。
      'host-src'是绝对路径或名称值。

         

    名称值必须以字母数字字符开头,后跟a-z0-9,_(下划线),. (期间)或 - (连字符)。绝对路径以/(正斜杠)开头。

    Manage data in containers (Removing volumes)

      

    删除容器后,Docker数据卷仍然存在。您可以创建命名或匿名卷。命名卷在容器外部具有特定的源表单,例如awesome:/bar。匿名卷没有特定的来源。

答案 2 :(得分:0)

使用docker-compose和docker run lines,一切都适合我。请注意,您不需要-P标志,文档说这会将所有公开的端口发布到随机端口 - 可能不是您想要的,因为您还指定了-p标志。 / p>

 -P, --publish-all                 Publish all exposed ports to random ports