docker-compose和manual命令之间的区别

Gar*_*rns 2 docker fig docker-compose

我想做什么

我想在一个docker容器中运行yesod web应用程序,链接到另一个docker容器中的postgres数据库.

我试过的

我有以下文件层次结构:

/
    api/
        Dockerfile
    database/
        Dockerfile
    docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)

运行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
Run Code Online (Sandbox Code Playgroud)

但是,如果我运行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
Run Code Online (Sandbox Code Playgroud)

我可以exportdocker-compose.yml文件中设置环境变量然后手动运行yesod devel并在localhost上成功访问我的站点.

最后,如果我sudo docker-compose run api自己运行,我会获得第三种不同的行为.这似乎成功启动但我无法在浏览器中访问该页面.通过运行sudo docker-compose run api /bin/bash我已经能够探索这个容器,我可以确认所设置的环境变量docker-compose.yml都已正确设置.

期望的行为

我希望得到我在后台运行数据库所得到的结果,然后只需运行就可以在api容器的shell中手动设置环境sudo docker-compose up.

显然,我正在尝试的三种不同的方法做了稍微不同的事情.但是根据我对docker和docker-compose的理解,我希望它们基本上是等价的.请有人解释他们的不同之处和原因,如果可能的话,我可以如何达到我想要的结果?

tha*_*tah 5

错误消息表明API容器期望来自命令行的输入,该命令行期望容器中存在TTY.

在"手动"启动中,您告诉docker通过-t标志(-itv简写为-i -t -v容器)在容器中创建TTY ,因此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
Run Code Online (Sandbox Code Playgroud)