docker-未找到撰写服务构建路径

docker-compose service build path not found

我的应用程序中有一个 rake 任务,它应该启动一个 TCP 服务器。 我已将 rake 命令移至 entrypoint.sh 文件,并在 docker-compose 中添加了新服务,称为 tcp.

那个tcp服务return路径不对,当我运行docker-compose up -d。我尝试了不同的设置方式,但没有成功。如何为 rake 任务构建 docker 图像?

unable to prepare context: path "/Users/mac_user/Projects/fmt100/lib/tasks/socketing.rake" not found

docker-compose.yml

version: '3.9'
services:
tcp:
    build: ./lib/tasks/socketing.rake
    depends_on:
      - app
      - database
      - redis
      - sidekiq
    env_file: .env
    volumes:
      - .:/app
      - tcp_server:/app/lib/tasks
    entrypoint: ./entrypoints/tcp-entrypoint.sh

volumes:
  tcp_server:

您应该build: 拥有包含您的 Rails 应用程序的同一图像。覆盖 command: 到 运行 的 Rake 任务。在 Compose 文件中,它应该大致如下所示:

version: '3.8'
services:
  tcp:
    build: .
    depends_on: [database, redis]
    env_file: .env
    command: rake socketing
  app:
    build: .
    depends_on: [database, redis]
    env_file: .env
    ports: ['3000:3000']
  database: { ... }
  redis: { ... }
  sidekiq: { ... }

sidekiq 容器可能看起来非常相似。

由于您有两个标记为 build: . 的容器,Compose 将尝试构建映像两次。但是,这些图像在相同的源代码树上具有相同的 Docker 文件和 运行。这意味着 Docker 的图层缓存将生效,第二次构建将 运行 非常快并且不会实际生成新图像。

要使其正常工作,您还需要正确构建 Docker 文件。重要的是,您将 运行 的实际命令作为 Docker 文件 CMD 而不是 ENTRYPOINT (或者至少它必须与您在docker-compose.yml)。与往常一样,确保图像是 self-contained 并包含其所有库依赖项和应用程序代码(请注意上面的 Compose 文件中缺少 volumes:)。

FROM ruby:2.7
WORKDIR /app
RUN gem install bundler:2.3.12
COPY Gemfile Gemfile.lock .
RUN bundle install
COPY . .
EXPOSE 3000
# ENTRYPOINT ["./entrypoint.sh"]
CMD rails server -b 0.0.0.0

您不应将命令放在 ENTRYPOINT 或入口点脚本中。相反,使用入口点进行一些 first-time 设置,并可能注入相关的包装器,如 Bundler。

#!/bin/sh
# entrypoint.sh

# Run database migrations, but only if we're running the main server.
if [ "" = rails -a "" == server ]; then
  bundle exec rake db:migrate
fi

# Run whatever command we were given under Bundler.
exec bundle exec "$@"

command: 非常容易覆盖,您提供的任何内容都会出现在脚本最后语句的 "$@" 中。因此,如果您想要一个 Pry 控制台,例如,您可以

docker-compose run app \
  rails console

这将覆盖命令行中的 command:,而图像的 ENTRYPOINT 保持不变。示例 Compose 文件对作为 Rake 任务启动的 TCP 服务器执行相同的操作(同样,我希望您的 Sidekiq worker 以相同的方式工作)。