2

我正在尝试做的事情

我想在一个 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.

问题

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

4

1 回答 1

6

错误消息表明 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
于 2015-03-23T21:55:02.697 回答