部署后Docker容器无法正常工作

时间:2019-08-22 05:47:14

标签: docker

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

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

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

.yml文件在snippet4中

和nginx .conf文件位于snippet5

可能是什么问题?

谢谢

Avner


编辑:

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

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

  • 选项2-使用修改后的docker-compose

  • 在本地计算机上创建映像,将其推送到docker存储库,从那里拉出图像

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

结束编辑:


snippet1 -原始容器正常工作

# 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

snippet2 -部署容器(当前仍在本地主机上使用已部署的容器)

# 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

snippet3 -已部署的容器不起作用

# 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

snippet4 -.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"

snippet5 -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';
        }

    }

}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您需要将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 ,尤其是如果您已经有用于映像的Dockerfile;在这里您描述的场景中,docker commit产生的图像与docker build自己不会有任何不同,只是它会丢失一些细节,例如默认的{{1} }运行。

正如评论者所建议的,在另一台机器上运行相同设置的最佳方法是set up a Docker registry(或使用Docker Hub之类的公共服务),CMD在其中构建的映像,仅复制docker push文件到新计算机,然后在其中运行docker-compose.yml。 (将其想象为启动容器的docker-compose up脚本。)您必须进行一些更改:将run.sh块替换为相关的build:并删除{{1} }引用本地源代码。如果需要数据库数据,则需要单独复制。

image: