docker-compose和手动命令的区别
我正在尝试做什么
我想在一个docker容器中运行一个yesod web应用程序,并链接到另一个docker容器中的postgres数据库。
我试过了
我有以下文件层次结构:
/ api/ Dockerfile database/ Dockerfile docker-compose.yml
docker-compose.yml
如下所示:
database: build: database api: build: api command: .cabal/bin/yesod devel # dev setting environment: - HOST=0.0.0.0 - PGHOST=database - PGPORT=5432 - PGUSER=postgres - PGPASS - PGDATABASE=postgres links: - database volumes: - api:/home/haskell/ ports: - "3000:3000"
运行sudo docker-compose up
无法启动api容器,或者像以前一样经常出现以下错误:
api_1 | Yesod devel server. Press ENTER to quit api_1 | yesod: <stdin>: hGetLine: end of file personal_api_1 exited with code 1
但是,如果我运行sudo docker-compose database up &
然后启动api容器而不使用compose,而是使用
sudo docker run -p 3000:3000 -itv /home/me/projects/personal/api/:/home/haskell --link personal_database_1:database personal_api /bin/bash
我可以export
在docker-compose.yml
文件中设置的环境variables,然后手动运行yesod devel
并在本地主机上成功访问我的站点。
最后,如果我运行sudo docker-compose run api
,我会得到第三种不同的行为。 这似乎开始成功,但我不能访问我的浏览器页面。 通过运行sudo docker-compose run api /bin/bash
我已经能够探索这个容器,我可以确认在docker-compose.yml
中设置的环境variables都设置正确。
期望的行为
我想从后台运行数据库中获得结果,然后通过简单地通过运行sudo docker-compose up
手动设置api容器的shell中的环境。
题
显然,我尝试的三种不同的方法做了些微不同的事情。 但是从我对docker和docker的理解来看,我期望它们在本质上是等价的。 请有人可以解释他们如何以及为什么会有所不同,如果可能的话,我可以如何实现我想要的结果?
该错误消息表明API容器正在等待来自命令行的input,该命令行期望在您的容器中存在TTY。
在你的“手动”开始,你告诉-itv
通过-t
标志在容器中创build一个TTY( -itv
是-i -t -v
缩写),所以API容器成功运行。
要在docker-compose中实现相同的function,您必须在docker-compose.yml
的API服务中添加一个tty
键并将其设置为true
;
database: build: database api: build: api tty: true # <--- enable TTY for this service command: .cabal/bin/yesod devel # dev setting