一个计算机技术爱好者与学习者

0%

好好学Docker:Docker部署JavaWeb项目

1. 部署要求

宿主机为CentOS7,上面安装了docker、nginx和mysql。

1、把已经开发好的JavaWeb项目(pandawork-start)部署到docker容器里。
2、该JavaWeb项目使用宿主机的mysql。
3、容器设置静态ip为192.168.34.10,80端口映射为宿主机28080端口。
4、nginx配置可以通过网址pandawork.voidking.com访问该JavaWeb项目。

2. 软件准备

1、《Docker安装tomcat服务》一文中配置好的ubuntu/tomcat镜像。

2、假设宿主机中的mysql数据库密码为voidking,那么需要修改pandawork-start项目中的数据库配置文件(mybatis-config.xml),主机修改为192.168.34.1,密码修改为voidking。

3、打包JavaWeb项目的war包一份。
在pom.xml所在文件夹,执行mvn package -Dmaven.test.skip=true命令,在target目录下就会生成war包。(把该war包放到tomcat的webapps文件夹里,会自动解压。)

4、使用xftp,上传war包到CentOS7的/download目录下。

3. 数据库准备

1、使用navicat连接到宿主机mysql。
2、创建数据库pandawork,数据库名为pandawork,字符集选择utf8–UTF-8 Unicode,排序规则选择utf8_general_ci。
3、导入pandawork-start项目中的pandawork.sql文件。

4. 部署项目

4.1. 部署war包

1、启动ubuntu/tomcat镜像。
docker run -i -t -v /download/:/mnt/software/ ubuntu/tomcat /bin/bash

2、移动war包到webapps。
cd /mnt/software

mv pandawork-start.war /opt/apache-tomcat-8.0.44/webapps/

3、启动tomcat,自动解压war包。
source /etc/profile

cd /opt/apache-tomcat-8.0.44/bin/

./startup.sh

4、测试访问。
curl localhost:8080/pandawork-start/hello

5、关闭tomcat。
./shutdown.sh

4.2. tomcat配置

1、配置tomcat端口为80。
cd /opt/apache-tomcat-8.0.44/conf/

vi server.xml

找到:

1
2
3
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

修改为:

1
2
3
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

2、配置域名访问。
找到:

1
<Engine name="Catalina" defaultHost="localhost">

修改为:

1
<Engine name="Catalina" defaultHost="pandawork.voidking.com">

找到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Host name="localhost"  appBase="webapps"
unpackWARs="true" autoDeploy="true">

<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->

<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Host name="pandawork.voidking.com"  appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="pandawork-start" reloadable="true" />

<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->

<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

4.3. 测试启动

1、启动tomcat。
cd /opt/apache-tomcat-8.0.44/bin/

./startup.sh

2、在/etc/hosts文件中,添加

1
127.0.0.1       pandawork.voidking.com

3、测试访问。
curl pandawork.voidking.com

4、关闭tomcat。
./shutdown.sh

4.4. 保存容器

1、退出容器
exit

2、查看dockerid
docker ps -l

3、保存容器为ubuntu/pandawork镜像。
docker commit 87be ubuntu/pandawork

5. 网络配置

1、创建自定义网络,选取192.168.34.0网段。

1
docker network create --subnet=192.168.34.0/24 voidkingnet

2、选取192.168.34.10作为静态IP地址,启动ubuntu/pandawork镜像。

1
docker run -d -p 28080:80 --name pandawork1.0 --add-host pandawork.voidking.com:127.0.0.1 --net voidkingnet --ip 192.168.34.10 ubuntu/pandawork /run.sh

我们已经在容器中修改了/etc/hosts文件,为什么还需要–add-host参数?
这是因为容器中的hosts文件,在重启后会恢复初始设置,改了也没用。

实际上,在容器中配置tomcat的时候,如果

1
<Engine name="Catalina" defaultHost="localhost">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Host name="localhost"  appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="pandawork-start" reloadable="true" />

<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->

<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

那么,–add-host参数不加也可以。貌似画蛇添足,实际上不然,有些项目可移植性比较差,必须配置本地hosts。

3、查看运行状态。
docker ps

4、测试访问。
curl 192.168.34.10或者curl localhost:28080

5、关闭容器
docker kill pandawork1.0

6、再次启动容器
docker start pandawork1.0

6. nginx配置

1、在宿主机中,找到nginx安装位置
ps aux | grep nginx

2、进入nginx配置目录
《在CentOS7上配置PHP运行环境》一文中,郝同学的nginx是通过EZHTTP安装的。

cd /usr/local/nginx/conf,进入nginx配置文件目录。
cd vhost,具体的某个站点的目录,都在vhost目录下。

3、修改nginx配置文件
参照项目:https://github.com/voidking/nginx-conf ,在vhost目录下,新建pandawork.voidking.com.conf文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
upstream pandawork{
server 192.168.34.10;
#server 192.168.34.11;用来负载均衡
}

server{
listen 80;
server_name pandawork.voidking.com;
location / {
proxy_pass http://pandawork;
}
}

4、重新加载nginx配置文件
cd /usr/local/nginx/sbin./nginx -s reload

报错:

1
nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)

解决办法:
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

然后重新执行./nginx -s reload

7. hosts配置

1、在宿主机中,修改/etc/hosts文件,添加:

1
127.0.0.1       pandawork.voidking.com

2、测试访问。
在宿主机中,curl pandawork.voidking.com

8. 最终测试

1、在宿主机中关闭防火墙,systemctl stop firewalld.service

2、假设宿主机IP为192.168.56.101,那么在宿主机同局域网PC中配置hosts:

1
192.168.56.101    pandawork.voidking.com

3、浏览器中输入http://pandawork.voidking.com,看到“Hello World!”。

4、验证注册登录等功能,全部正常。此次,大功告成。

9. 重启宿主机后报错

重新启动宿主机后,启动docker,启动pandawork容器。
执行docker start pandawork1.0时,报错如下:

1
2
Error response from daemon: driver failed programming external connectivity on endpoint pandawork1.0 (9f3cbc9ebc5030c0cbbbbbac81628ce48374fd392f6995f4d75ac20bce9d2a30):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 28080 -j DNAT --to-destination 192.168.34.10:80 ! -i br-024154a13bb1: iptables: No chain/target/match by that name.
(exit status 1))

解决办法:
pkill docker

iptables -t nat -F

ifconfig docker0 down

最后重启docker,docker restart docker

10. 书签

Docker部署JavaWeb项目实战

使用 Docker 搭建 Java Web 运行环境

解决docker容器中文乱码,修改docker容器编码格式