我想在一个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
文件中设置环境变量,然后手动运行yesod devel
并在localhost上成功访问我的网站。
最后,如果我自己运行sudo docker-compose run api
,我会获得第三种不同的行为。这似乎已成功启动,但我无法在浏览器中访问该页面。通过运行sudo docker-compose run api /bin/bash
,我已经能够探索此容器,并且我可以确认docker-compose.yml
中设置的环境变量都已正确设置。
我想通过在后台运行数据库获得我实现的结果,然后只需运行sudo docker-compose up
即可在api容器的shell中手动设置环境。
显然,我尝试的三种不同方法做了稍微不同的事情。但是根据我对docker和docker-compose的理解,我希望它们基本上是等价的。请有人解释他们之间的差异和原因,如果可能的话,我可以如何达到我想要的结果?
答案 0 :(得分:5)
错误消息表明API容器需要来自命令行的输入,该命令行需要TTY存在于容器中。
在你的&#34;手册&#34;开始,您告诉docker通过-t
标志在容器中创建TTY(-itv
是-i -t -v
的简写),因此API容器成功运行。
要在docker-compose中实现相同功能,您必须在tty
中为API服务添加docker-compose.yml
密钥,并将其设置为true
;
database:
build: database
api:
build: api
tty: true # <--- enable TTY for this service
command: .cabal/bin/yesod devel # dev setting