为啥docker容器内无法启动tomcat,容器外可以

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥docker容器内无法启动tomcat,容器外可以相关的知识,希望对你有一定的参考价值。

参考技术A 步骤1:为我们的容器创建第一个镜像
# 以 centos 镜像作为基础镜像,我们启动自己的容器并在其中执行/bin/bash命令
# 注:-t -i 参数用于创建一个虚拟的命令行。
sudo docker run -t -i centos /bin/bash
现在我们已经成功的运行了自己的第一个容器,并且进入到容器的命令行界面中。在容器中,我们执行下面的命令:

yum -y update # 更新软件包
yum install which # 安装which命令
yum install git # 安装Git

安装完成后,按 Ctrl + d 来退出容器的命令行。
# 执行sudo docker ps -a,可以看到被我们终止的容器
CONTAINER ID IMAGE COMMAND CREATED……
da9031d3568f centos:6.4 /bin/bash 5 minutes ago…..
把我们所做的改变提交到一个新的容器:
# 这里我们创建一个自己的基础容器,容器中安装好了文章中所需的常用工具。读者的容器 id 可能与文章中的有所不同,以上一步 docker ps -a 的结果为准。
sudo docker commit da90 custom/base
容器成功提交后,执行 sudo docker images ,我们会看到刚才提交的容器(如下面的结果所示)。我们就以这个容器为基础容器,再来创建一个新的容器。
REPOSITORY TAG IMAGE ID CREATED
custom/base latest 05b6cecd370b 2 minutes ago
centos 6.4 539c0211cd76 10 months ago
centos latest 539c0211cd76 10 months ago…
步骤2:创建新的容器,并安装 apache
# 以 custom/base 容器为基础,运行一个新的容器。

sudo docker run -t -i custom/base /bin/bash

# 安装 httpd

yum install httpd

步骤3:再次提交新的容器
按 Ctrl + d 来退出容器的命令行,然后执行命令:
# 这个命令会把步骤2中我们安装 httpd 带来的改变提交到新的名为 custom/httpd 的容器镜像中。你的容器 id 可能会和文章中有所不同,以 sudo docker ps -a 命令的结果为准。

sudo docker commit aa6e2fc0b94c custom/httpd

你应该已经发现了,我们创建了一个带有 http 服务器并可以复用的容器镜像。你可以根据这种思想,为自己所需的每个组件都创建一个容器,然后把这些容器复用于开发环境或者生产环境。
步骤7:运行 http 服务器
# -v will Mount a volume from VM to the container which was also shared from host to Vagrant VM.
# -v 参数把主机共享给虚拟机的一个卷挂载到容器中
# -p forward VM port 80 to container port 80; VM port 80 is mapped to host port 8080 in Vagrantfile
# -p 参数把虚拟机的80端口映射到容器的80端口;虚拟机的80端口在 Vagrantfile 中被绑定到主机的8080端口,也就是:主机8080->虚拟机80->容器80
sudo docker run -t -i -p 80:80 -v /vagrant/htdocs:/var/www/html custom/httpd /bin/bash
# 启动 Apache
apachectl -k start本回答被提问者采纳

Dockerizing React App:应用程序在容器内启动,但无法从暴露的端口访问

【中文标题】Dockerizing React App:应用程序在容器内启动,但无法从暴露的端口访问【英文标题】:Dockerizing a React App: The app starts inside the container, but it not accessible from the exposed port 【发布时间】:2018-10-28 06:26:03 【问题描述】:

这是一个专门针对教程的问题:http://mherman.org/blog/2017/12/07/dockerizing-a-react-app/#.Wv3u23WUthF by Michael Herman

问题:应用程序在容器内启动,但无法从我刚刚暴露的端口-p 3000:3000 访问它。当浏览到 localhost:3000 时收到 无法访问此站点 错误

docker-compose.yaml

version: '3.5'

services:

  sample-app:
    container_name: sample-app
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - '.:/usr/src/app'
      - '/usr/src/app/node_modules'
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development

Dockerfile

# base image
FROM node:9.6.1

# set working directory
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH

# install and cache app dependencies
COPY package.json /usr/src/app/package.json
RUN npm install --silent
# RUN npm install react-scripts@1.1.1 -g --silent # Uncomment to silent logs
RUN npm install react-scripts@1.1.1 -g 

# start app
CMD ["npm", "start"]

#CMD tail -f /usr/src/app/README.md


###################################
# To Run sample app:
# docker run -it -v $PWD:/usr/src/app -v /usr/src/app/node_modules -p 3000:3000 --rm sample-app

Docker 日志:https://docs.google.com/document/d/14LRCgjMLAkmdMiuedxAW2GWUAtxmWeJQCNQB2ezdYXs/edit

在运行 compose 或单个容器之后。它显示成功启动,但此后什么也没有。

当我 docker exec 进入容器时,$ curl localhost:3000 返回正确的 index.html 页面

我使用以下任一方式启动容器:

$ docker run -it -v $PWD:/usr/src/app -v /usr/src/app/node_modules -p 3000:3000 --rm sample-app

sample-app存在)

$ docker-compose up

【问题讨论】:

你的应用在监听哪个端口? 3000。正如我上面所说:当我 docker exec 进入容器时,$ curl localhost:3000 返回正确的 HTML 页面 (index.html)。这应该证明应用程序已启动并正在运行,正在收听:3000 尝试将 EXPOSE 3000 添加到您的 Dockerfile 中 已经试过EXPOSE 3000,没区别。 【参考方案1】:

在消除所有其他因素后,我假设您的应用程序正在侦听 localhost。本地主机的范围仅限于容器本身。因此,为了能够连接到它,您必须在容器内。

要解决此问题,您需要让您的应用程序改为监听 0.0.0.0。

【讨论】:

【参考方案2】:

问题是您将应用程序严格暴露在 localhost 上。 你必须修改你的package.json 来改变它:

"start": "http-server -a localhost -p 3000"

进入:

"start": "http-server -a 0.0.0.0 -p 3000"

如果您的package.json 的内容与上面的内容有很大不同,重要的部分是-a 选项 - 它必须指向0.0.0.0,因为这意味着http-server 将侦听所有传入的连接。

如果您不确定要更改什么,只需在您的问题中发布package.json 的基本部分,以便我们检查。

【讨论】:

啊,你是,虽然我不想删除我的答案,因为我详细解释了解决方案并希望社区会发现我的答案很有用;) @LeonardCapacete @trust512 我希望它们都结合在一个答案中,每个答案都有一条信息,而另一个则丢失了。正如 trust512 所说,我的服务器不同,所以我不得不这样做:webpack-dev-server --host 0.0.0.0 --port 3000。请注意,-a 0.0.0.0 -p 3000 不适用于 webpack-dev-server 你总是可以接受一个(更多的积分)并支持另一个(更少的积分但仍然奖励);)【参考方案3】:

我在使用create-react-app 时遇到了同样的问题,但我设法通过不暴露Dockerfile 中的docker 端口并运行以下命令docker container run -p ANY_PORT_YOU_WANT:**3000** -d image_name 来解决它。碰巧的是,默认情况下,react-server 在 docker 容器中的 PORT 3000 上运行,并且通过暴露 3000 以外的任何其他端口,该连接流被终止。启动脚本默认使用0.0.0.0。见Issue

【讨论】:

以上是关于为啥docker容器内无法启动tomcat,容器外可以的主要内容,如果未能解决你的问题,请参考以下文章

大项目docker打包部署慢

如何实现docker服务重启容器不停止

Docker 使用 tomcat镜像部署web网站无法访问

7.Docker技术入门与实战 --- 端口映射与容器互联

Docker配置Tomcat容器的过程

Docker配置Tomcat容器的过程