【问题标题】:How can I run a Docker container on a remote server in the same manner as docker-compose up?如何以与 docker-compose up 相同的方式在远程服务器上运行 Docker 容器?
【发布时间】:2020-11-22 03:24:06
【问题描述】:

TL;DR:docker-compose up 工作正常时,/docker-entrypoint.sh: line 10: exec: nginx: cannot execute: Is a directory 运行 docker run username/srdc_prod:2020.07.26 时出现错误。

我有一个已推送到 DockerHub 的 docker 容器。我可以使用 docker-compose up 在本地运行它。我在我的远程服务器上拉下了这个,现在我正在尝试使用docker run username/srdc_prod:2020.07.26

当我这样做时,我收到错误/docker-entrypoint.sh: line 10: exec: nginx: cannot execute: Is a directory。执行 docker-compose up 在本地工作得很好。我想将此图像推送到 Docker Hub 并将其拉下并在我的远程服务器上运行它。但是,我不能使用docker-compose up,因为docker-compose.yaml 文件远程不存在。我意识到我可以尝试远程克隆我的 GitHub 存储库,然后运行 ​​docker-compose up,但这违背了将容器推送到 DockerHub 并最终设置 CI/CD 的目的。

有没有办法在容器上运行 docker-compose up?或者是否可以看到所有执行的命令?我在this question 中看到我可以使用docker ps --no-trunc 查看为运行docker 容器执行的所有命令,但所有这些都依赖于我似乎无法远程执行的docker-entrypoint.sh 文件。我是不是做错了,我需要重构我的 Dockerfile 以在远程服务器上运行?

远程服务器上的图像

username@ubuntu-512mb-name:~$ docker image ls
WARNING: Error loading config file: /home/username/.docker/config.json: stat /home/username/.docker/config.json: permission denied
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
username/srdc_prod        2020.07.26          af62927882ee        5 days ago          504MB

docker-entrypoint.sh

  1 #!/bin/bash
  2
  3 echo "Collect static files"
  4 python manage.py collectstatic --noinput
  5
  6 echo "Apply database migrations"
  7 python manage.py migrate --noinput
  8
  9 echo "Starting daphne server"
 10 exec "$@" # offending line

Dockerfile

FROM python:3-alpine

# set env vars
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN mkdir /app

RUN apk update && apk add --no-cache postgresql-dev gcc libffi-dev musl-dev build-base python3-dev bash

COPY requirements.txt /app/requirements.txt
RUN pip install --upgrade pip && pip install --no-cache-dir -r /app/requirements.txt

COPY test-requirements.txt /app/test-requirements.txt
RUN pip install --upgrade pip && pip install --no-cache-dir -r /app/test-requirements.txt

COPY . /app
# set working directory
WORKDIR /app

RUN mkdir -p /var/www/srdc/static/
RUN chmod 755 /var/www/srdc/static/

EXPOSE 8000

ENV DJANGO_SETTINGS_MODULE=srdc.settings

CMD ["nginx", "-g", "daemon off;"]

ADD docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod a+x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]

docker-compose.yml

version: '3'

services:
  django_web:
    build: .
    command: bash -c "daphne -b 0.0.0.0 -p 8000 srdc.asgi:application"
    expose:
       - 8000
    image: srdc:v0
    container_name: srdc_django_web
    volumes:
      - .:/app
      - static_volume:/var/www/srdc/static/
    depends_on:
      - db
  nginx:
    build: ./nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - static_volume:/var/www/srdc/static/
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    depends_on:
      - django_web
  db:
    image: postgres
    container_name: "my_postgres"
    ports:
      - "54320:5432"
    volumes:                                                                                                                                                                                     - my_dbdata:/var/lib/postgresql/data
volumes:                                                                                                                                                                                       my_dbdata:
    static_volume:                                                                                                                                                                             media_volume:

【问题讨论】:

  • 也许我遗漏了一些东西,但在你的 Dockerfile 中你似乎没有安装 nginx,但你的 CMDnginx -g ...。该命令应该是daphne ...吗?
  • 有一个名为 'nginx' 的目录有一个 Dockerfile。我可能应该包括那个。
  • 但这就是Dockerfilenginx 服务,对吧?您的问题似乎与 django_web 服务有关,基于您正在运行的映像 (srdc_prod),它不需要 nginxDockerfile。您列出了三个容器,看起来您在错误的容器中运行了 nginx 命令。

标签: python docker nginx docker-compose


【解决方案1】:

您看到的错误是准确的:nginx 是一个目录。根据您的 docker-compose.yml 清单,您的根目录中有一个 nginx 文件夹,您可以将其用作 nginx 服务的构建上下文。

  nginx:
    build: ./nginx # Here's the evidence for the nginx folder.
    ports:

构建django_web 映像时,会将整个上下文目录复制到/app,其中包括nginx 目录。

COPY . /app
# set working directory
WORKDIR /app

您的username/srdc_prod 图像的CMDnginx -g daemon off;,由您的docker-entrypoint.sh 执行。失败是因为 nginx 是一个目录。

根据您的 docker-compose.yml 清单,您实际想要的 CMD 似乎是 daphne -b 0.0.0.0 -p 8000 srdc.asgi:application 或类似的东西,但不是 nginx,它没有安装在基于 alpine 的映像中。

问题范围之外的一些建议。

  1. 如果您在 dev 中使用 docker-compose,请考虑在您的托管环境中也使用它,而不是运行原始的 docker run 命令。
  2. 更好的是,在 swarm 模式下使用 Docker。您可以通过这种方式重新使用清单文件,尽管您需要删除一些已弃用的内容(例如depends_on)并稍微扩展服务定义。使用 swarm 模式(或其他一些编排工具)可以让您在未来更轻松地扩展您的服务,此外您还可以获得其他一些方便的功能,例如机密、重启策略、网络隔离等。

【讨论】:

  • 谢谢。你能详细说明一下这个If you're using docker-compose in dev, consider using that in your hosted environments, too, instead of running the raw docker run commands.吗?如果不将 repo 克隆到远程服务器上,我没有看到一个简单的方法。我会研究群体模式。谢谢!
  • 通常你不需要在远程服务器上放任何东西,除了 docker-compose.yml 文件,也许还有一些用于配置的 env 文件。所有镜像都应该存在于云中的某个容器注册表中,并且每个镜像都应该具有运行所需的一切(即所有应用程序代码和资产等等)。在你共享的 YAML 文件中,django 容器挂载了./app 目录,但在构建的镜像中app 被复制到容器中。因此,您不需要在远程服务器上克隆 repo。
  • 所以在这个设置中我需要维护两个单独的 docker-compose.yaml 文件?你有任何链接可以指向我在产品中运行 docker-compose 吗?谢谢!
  • 我没有任何链接,抱歉。我在产品、QA 和 UAT 中使用 Docker Swarm。我个人只在所有环境中使用一个 docker-compose.yml 文件,但我为每个环境都有单独的环境文件。 IMO,所有环境中的服务定义都应该相同,并且从 env 到 env 的变化应该可以使用环境变量进行配置。
猜你喜欢
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
相关资源
最近更新 更多