如何在生产 Dockerfile 中使用应用程序文件

How to use application files in production Dockerfile

我正在学习 Docker 并希望得到一些智慧。

我目前对 Docker 的假设是 Docker 文件和由此生成的图像仅存储实际环境本身。而不是应用程序 files/server。我们利用 Volumes 在容器中存储和 运行 应用程序代码。在需要动态安装的生产 Docker 示例中。如何在图像本身中使用应用程序代码(因为它没有存储在图像中……对吗?)。

当我在开发中使用我的 Docker 图像时,我启动了一个容器,其中安装了我本地工作目录的卷。这是我执行此操作的命令。

docker run -v $(pwd):/app image_name

1.我是否从实际 Docker 文件中的 GitHub 中提取以在容器中添加和使用应用程序代码?

2。有没有办法将应用程序代码存储在 Docker 图像本身?

例如,这是我非常简单的Docker文件:

FROM ruby:3.1.1-alpine3.15

RUN apk update -q
RUN apk add bash yarn git build-base nodejs mariadb-dev tzdata

ENV RAILS_ENV production

WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock

RUN gem install bundler
RUN gem update bundler
RUN bundle install

COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

提前致谢,如有任何建议,我们将不胜感激。

编辑 22 年 5 月 16 日

感谢 Joe 和 David Maze 阐明构建 Docker 图片的工作原理。

这是我修改后的 Docker 文件,一旦构建,它就会在 Docker 图像中包含我的应用程序代码。利用 COPY . .

FROM ruby:3.1.1-alpine3.15

RUN apk update -q
RUN apk add bash yarn git build-base nodejs mariadb-dev tzdata

ENV RAILS_ENV production

WORKDIR /app

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock

RUN gem install bundler
RUN gem update bundler
RUN bundle install

COPY . .

COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

我还在用

COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock

COPY package.json /app/package.json
COPY yarn.lock /app/yarn.lock

根据 David Maze 对此 post 的回答。因为捆绑和安装依赖项需要很长时间。将来当我更改我的应用程序代码但我的依赖项没有更改时,Docker 可以检测到它们没有更改并重用以前的图像层,同时跳过我的 RUN bundle install 步骤。使图像构建时间更快。

这个修改后的 Docker 文件允许我从图像启动一个 Docker 容器,我的应用程序代码已经使用这个命令。

docker run image_name

我还可以通过覆盖 Docker 文件的环境变量在开发环境中启动 Rails 服务器。

docker run -e RAILS_ENV=development image_name

再次感谢!

Dockerfile 用于创建带有命令行指令列表的自动构建。你可以在你的镜像中复制整个代码库,一个简单的 rails dockerfile 就像:

FROM ruby:2.6.6-alpine

RUN apk update && apk add bash build-base nodejs postgresql-dev tzdata git openssh
RUN mkdir /project

WORKDIR /project

ENV RAILS_ENV development

COPY Gemfile Gemfile.lock ./
RUN gem install bundler --no-document
RUN bundle install --no-binstubs --jobs $(nproc) --retry 3

COPY . .

CMD ["rails", "server", "-b", "0.0.0.0"]

这里COPY . .会把当前目录的内容(你的代码)复制到最终的镜像中。 您可以使用 docker-compose 构建多个图像,例如。网络应用 + 数据库:

docker-compose.yml

services:
  db:
    image: 'postgres:11-alpine'
    volumes:
      - 'postgres:/var/lib/postgresql/data'
    ports:
      - '5432:5432'
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust
    container_name: 'project-db'
    restart: on-failure

  web:
    depends_on:
      - 'db'
    build:
      context: .
      dockerfile: ./Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    ports:
      - '3000:3000'
    environment:
      - DATABASE_HOST=db
    container_name: 'project-rails'
    restart: on-failure

volumes:
  db:
  postgres:

在这里,您可以定义卷、文件夹以在图像出现故障时保留。 当您第一次构建图像​​时(例如 docker-compose up --build),Docker 将下载基础图像(如果您的机器上还没有),它将构建并 运行 它们。 当您更新代码库并启动新版本时,Docker 将缓存未更改的图像层并仅重建您修改的内容。