【问题标题】:Docker containers not working after deployDocker 容器在部署后不工作
【发布时间】:2019-09-30 06:19:00
【问题描述】:

我有一组从 yaml 文件生成的 docker 容器。这些容器工作正常 - 我可以访问 localhost,从 nginx 容器 ping http://web,并列出端口映射(参见 sn-p1)

我现在想将它们部署到另一台机器上,所以我使用 docker 提交、保存、加载和运行来创建映像、复制映像并部署新容器(参见 sn-p2)。

但在我部署容器后,它们无法正常运行(我无法访问 localhost,无法从 nginx 容器 ping http://web,并且端口映射为空 - 请参阅 sn-p3)

.yml 文件在 sn-p4 中

nginx .conf 文件在 sn-p5 中

可能是什么问题?

谢谢,

Avner


编辑:

从下面的回复中,我了解到我应该使用以下两个选项之一在远程主机上构建容器,而不是使用“docker commit”:

  • option1 - 将代码复制到远程主机并应用修改后的 docker-compose,并使用修改后的 docker-compose 从源代码构建

  • 选项 2 - 在本地机器上创建一个镜像,将其推送到 docker 存储库,然后使用修改后的 docker-compose 从那里拉取它

我正在尝试遵循 option1(作为开始),但仍有问题。 我提交了一个描述问题的新帖子here

结束编辑:


sn-p1 - 原始容器工作正常

# the original containers
docker ps 
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS                         NAMES
26ba325e737d        webserver_nginx      "nginx -g 'daemon of…"   3 hours ago         Up 43 minutes       0.0.0.0:80->80/tcp, 443/tcp   webserver_nginx_1
08ef8a443658        webserver_web        "flask run --host=0.…"   3 hours ago         Up 43 minutes       0.0.0.0:8000->8000/tcp        webserver_web_1
33c13a308139        webserver_postgres   "docker-entrypoint.s…"   3 hours ago         Up 43 minutes       0.0.0.0:5432->5432/tcp        webserver_postgres_1


# can access localhost
curl http://localhost:80
<!DOCTYPE html>
...


# can ping web container from the nginx container
docker exec -it webserver_nginx_1 bash
root@26ba325e737d:/# ping web
PING web (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.138 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.123 ms
...


# List port mappings for the container
docker port webserver_nginx_1
80/tcp -> 0.0.0.0:80

sn-p2 - 部署容器(目前仍在使用本地主机上部署的容器)

# create new docker images from the containers
docker commit webserver_nginx_1 webserver_nginx_image2
docker commit webserver_postgres_1 webserver_postgres_image2
docker commit webserver_web_1 webserver_web_image2

# save the docker images into .tar files
docker save webserver_nginx_image2 > /tmp/webserver_nginx_image2.tar
docker save webserver_postgres_image2 > /tmp/webserver_postgres_image2.tar
docker save webserver_web_image2 > /tmp/webserver_web_image2.tar

# load the docker images from tar files
cat /tmp/webserver_nginx_image2.tar | docker load
cat /tmp/webserver_postgres_image2.tar | docker load
cat /tmp/webserver_web_image2.tar | docker load

# Create containers from the new images
docker run -d --name webserver_web_2 webserver_web_image2
docker run -d --name webserver_postgres_2 webserver_postgres_image2
docker run -d --name webserver_nginx_2 webserver_nginx_image2


# stop the original containers and start the deployed containers
docker stop webserver_web_1 webserver_nginx_1 webserver_postgres_1
docker stop webserver_web_2 webserver_nginx_2 webserver_postgres_2
docker start webserver_web_2 webserver_nginx_2 webserver_postgres_2

sn-p3 - 部署的容器不起作用

# the deployed containers
docker ps 
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS               NAMES
15ef8bfc0ceb        webserver_nginx_image2      "nginx -g 'daemon of…"   3 hours ago         Up 4 seconds        80/tcp, 443/tcp     webserver_nginx_2
d6d228599f81        webserver_postgres_image2   "docker-entrypoint.s…"   3 hours ago         Up 3 seconds        5432/tcp            webserver_postgres_2
a8aac280ea01        webserver_web_image2        "flask run --host=0.…"   3 hours ago         Up 4 seconds        8000/tcp            webserver_web_2


# can NOT access localhost
curl http://localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused


# can NOT ping web container from the nginx container
docker exec -it webserver_nginx_2 bash
root@15ef8bfc0ceb:/# ping web
ping: unknown host

# List port mappings for the container
docker port webserver_nginx_2
# nothing is being shown

sn-p4 - .yml 文件

cat /home/user/webServer/docker-compose.yml

version: '3'

services:
  web:
    restart: always
    build: ./web
    expose:
      - "8000"
    volumes:
      - /home/user/webServer/web:/home/flask/app/web
    command: /usr/local/bin/gunicorn -w 2 -t 3600 -b :8000 project:app
    depends_on:
      - postgres
    stdin_open: true
    tty: true

  nginx:
    restart: always
    build: ./nginx
    ports:
      - "80:80"
    volumes:
      - /home/user/webServer/web:/home/flask/app/web
    depends_on:
      - web

  postgres:
    restart: always
    build: ./postgresql
    volumes:
      - data1:/var/lib/postgresql
    expose:
      - "5432"

volumes:
  data1:

,

cat /home/user/webServer/docker-compose.override.yml

version: '3'

services:
  web:
    build: ./web
    ports:
      - "8000:8000"
    environment:
      - PYTHONUNBUFFERED=1
      - FLASK_APP=run.py
      - FLASK_DEBUG=1
    volumes:
      - /home/user/webServer/web:/usr/src/app/web
      - /home/user/webClient/:/usr/src/app/web/V1
    command: flask run --host=0.0.0.0 --port 8000

  nginx:
    volumes:
      - /home/user/webServer/web:/usr/src/app/web
      - /home/user/webClient/:/usr/src/app/web/V1
    depends_on:
      - web

  postgres:
    ports:
      - "5432:5432"

sn-p5 - nginx .conf 文件

cat /home/user/webServer/nginx/nginx.conf

# Define the user that will own and run the Nginx server
user  nginx;
# Define the number of worker processes; recommended value is the number of
# cores that are being used by your server
worker_processes  1;

# Define the location on the file system of the error log, plus the minimum
# severity to log messages for
error_log  /var/log/nginx/error.log warn;
# Define the file that will store the process ID of the main NGINX process
pid        /var/run/nginx.pid;


# events block defines the parameters that affect connection processing.
events {
    # Define the maximum number of simultaneous connections that can be opened by a worker process
    worker_connections  1024;
}


# http block defines the parameters for how NGINX should handle HTTP web traffic
http {
    # Include the file defining the list of file types that are supported by NGINX
    include       /etc/nginx/mime.types;
    # Define the default file type that is returned to the user
    default_type  text/html;

    # Define the format of log messages.
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # Define the location of the log of access attempts to NGINX
    access_log  /var/log/nginx/access.log  main;

    # Define the parameters to optimize the delivery of static content
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay    on;

    # Define the timeout value for keep-alive connections with the client
    keepalive_timeout  65;

    # Define the usage of the gzip compression algorithm to reduce the amount of data to transmit
    #gzip  on;

    # Include additional parameters for virtual host(s)/server(s)
    include /etc/nginx/conf.d/*.conf;
}

,

cat /home/user/webServer/nginx/myapp.conf

# Define the parameters for a specific virtual host/server
server {

    # Define the server name, IP address, and/or port of the server
    listen 80;

    # Define the specified charset to the “Content-Type” response header field
    charset utf-8;

    # Configure NGINX to deliver static content from the specified folder
    location /static {
        alias /home/flask/app/web/instance;
    }

    location /foo {
        root /usr/src/app/web;
        index index5.html;
    }

    location /V1 {
        root /usr/src/app/web;
        index index.html;
    }

    # Configure NGINX to reverse proxy HTTP requests to the upstream server (Gunicorn (WSGI server))
    location / {
        root /;
        index index1.html;

        resolver 127.0.0.11;
        set $example "web:8000";
        proxy_pass http://$example;

        # Redefine the header fields that NGINX sends to the upstream server
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Define the maximum file size on file uploads
        client_max_body_size 10M;
        client_body_buffer_size 10M;


        if ($request_method = 'OPTIONS') {
           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           #
           # Custom headers and headers various browsers *should* be OK with but aren't
           #
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           #
           # Tell client that this pre-flight info is valid for 20 days
           #
           add_header 'Access-Control-Max-Age' 1728000;
           add_header 'Content-Type' 'text/plain; charset=utf-8';
           add_header 'Content-Length' 0;
           return 204;
        }
        if ($request_method = 'POST') {
           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }
        if ($request_method = 'GET') {
           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
           add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
           add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        }

    }

}

【问题讨论】:

  • 这不是将 Docker 容器部署到新机器的方式。将构建映像所需的文件、Dockerfile 和 compose 文件复制到新服务器,然后只需使用 docker-compose up -d 命令即可。
  • @7_R3X 诚然并不理想(轻描淡写)但可能,OP 只需将 docker-compose 配置映射到 docker run 参数 - 即 ref。 sn-p2,不发布任何端口(即-p 80:80 -p 443:443)所以def。将无法连接到本地主机。
  • @masseyb:我同意你的观点,我会编辑我的答案以包含你的建议,但我相信在这里,在 StackOverflow,我们不仅应该帮助人们解决他们的问题,还应该帮助他们培养最佳实践。没有不尊重。
  • @7_R3X 是肯定的。但是有不止一种方法可以做到这一点 - 例如。我会构建图像,将它们推送到注册表,然后在机器上拉取并运行它们(没有 docker-compose 用于构建、实验功能和 buildkit,可能用于运行时,但我定义不会在部署它们的实例 - 而是保持集中,维护多个 docker 守护进程以进行构建可能会变得很麻烦 - 或 docker 中的 docker)。
  • 感谢 cmets。我正在遵循您的建议,但仍有问题。我在here 中提交了一个单独的帖子

标签: docker


【解决方案1】:

您需要将docker-compose.yml 文件复制到目标机器(进行一些编辑)并在那里重新运行它。如果您不在那里重建图像,则需要修改文件以不包含引用本地源代码树的volumes:,并更改build: 块以引用一些image:。永远不要运行docker commit

docker-compose.yml 文件主要包含与docker run 选项等效的选项,但语法更方便。例如,当docker-compose.yml

services:
  nginx:
    ports:
      - "80:80"

这相当于一个docker run -p 80:80 选项,但是当你以后这样做时

docker run -d --name webserver_nginx_2 webserver_nginx_image2

缺少该选项。 Docker Compose 也 implicitly creates a Docker network for you 并且没有等效的 docker run --net 选项,容器之间的连接不起作用。

每次docker run 容器时都必须指定所有这些选项。 docker commit 不会保留它们。一般来说你永远不应该运行docker commit,特别是如果你的镜像已经有Dockerfiles;在您在这里描述的场景中,来自docker commit 的图像与您自己的docker build 没有任何不同,只是它会丢失一些细节,例如默认运行的CMD

正如评论者所建议的那样,在不同的机器上运行相同设置的最佳方法是 set up a Docker registry(或使用像 Docker Hub 这样的公共服务),docker push 你在那里构建的图像,只复制 docker-compose.yml文件到新机器,并在那里运行docker-compose up。 (把它想象成启动容器的run.sh 脚本。)您必须进行一些更改:将build: 块替换为相关的image: 并删除引用本地源代码的volumes:。如果您需要数据库数据,则需要单独复制。

services:
  web:
    restart: always
    image: myapp/web
    depends_on:
      - postgres
    ports:
      - "8000:8000"
    # expose:, command:, and core environment: should be in Dockerfile
    # stdin_open: and tty: shouldn't matter for a Flask app
    # volumes: replace code in the image and you're not copying that

【讨论】:

  • 感谢 cmets。我正在遵循您的建议,但仍有问题。我在here 中提交了一个单独的帖子
【解决方案2】:

您尝试在另一台服务器上部署应用程序的方式并不是 Docker 建议您这样做的方式。您需要传输所有需要存在的文件,以使应用程序与Dockerfile 一起运行以构建映像和docker-compose.yml 以定义如何部署应用程序的每个服务。 Docker 有一个不错的document to get started with

如果您打算将应用程序部署在另一台服务器上以实现冗余而不是创建副本,请考虑使用docker with swarm mode

【讨论】:

  • 感谢您的 cmets @7_R3X。我正在遵循您的建议,但仍有问题。我在here 中提交了一个单独的帖子。你能在那里提出一个解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 2017-02-03
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多