小试Docker

正式全职做开发已经半年了,两台服务器作开发,Oracle/MySQL/Nexus/Jenkins/Redis/ActiveMQ,一大堆的东东,还好有一些Linux的经验(上次CentOS被人挖矿,下次再说如何抓别人的),搭建这些东西都是比较容易的,当然不包括调优。就算自己搭建这些东西不难,但是真的比较费时间。后来有一个想法就是用Docker,今天搞了大半天终于搞定了。记下来,便于以后自己翻查吧。

后台架构

前台用的是Vue来开发,后台Nginx处理静态文件,反向代理请求到Tomcat,Tomcat再到Redis/ActiveMQ/MySQL。

所以后台需要Nginx, Tomcat, Redis, MySQL这些软件。根据调用关系,先把底层的服务开启。Docker安装就看官方文档吧。

Redis服务

首先将Redis的镜像(image)给拉到本地,然后开动。

1
2
3
4
5
6
7
docker pull redis
docker run --name redis -p 6379:6379 --privileged -v `pwd`/redis:/data -v `pwd`/redis/redis.conf:/etc/redis/redis.conf -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -d redis redis-server /etc/redis/redis.conf
-----
docker exec -it redis /bin/bash
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
echo "net.core.somaxconn = 65536" >> /etc/sysctl.conf
sysctl -p

docker run里面的参数含义分别是:

  • name:给container取名字,方便以后操作,要不得填container ID,很不友好。
  • p:官方解释Publish a container's port(s) to the host,我的理解就是相当于一个端口映射吧。将主机的端口映射到容器的端口。
  • privileged:官方解释Give extended privileges to this container,主要是要修改一些container参数,要不会提示一些Warning。
  • v:Bind mount a volume,将host文件或目录挂载到container,这样可以直接在host修改一些配置文件或container产生的一些文件存在host。
  • d:Run container in background and print container ID,后台运行。

然后redis需要远程访问,就要修改redis.conf,把bind给注释掉,protedted-mod改为no

MySQL服务

1
docker run --name mysql -e MYSQL_ROOT_PASSWORD=your-mysql-root-password -p 3306:3306 -v `pwd`/mysql:/var/lib/mysql -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone -d mysql/mysql-server

注意将其中的your-mysql-root-password改为自己的密码。

这时MySQL的root不能远程访问,放狗搜的话一大堆。

1
2
docker exec -it mysql /bin/bash
mysql -u root -p
1
2
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your-mysql-root-password' WITH GRANT OPTION;
FLUSH RIVILEGES

Tomcat服务

1
docker run --name tomcat -p 8080:8080 -v `pwd`/tomcat/webapps:/usr/local/tomcat/webapps -v `pwd`/tomcat/conf/tomcat-users.xml:/usr/local/tomcat/conf/tomcat-users.xml -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone --link redis:redis --link mysql:mysql -d andreptb/tomcat

--link主要是一个container连接到另一个contaner,好像是在container的/etc/hosts加上到另一个容器的地上,然后environment里加一些环境变量。这个只是我的猜测,等过段里子好好看看Docker的文件后再深入了解下。

这样在tomcat的应用中可以把jdbc.url里的host直接填mysql,redis的host填redis。比如jdbc.url=jdbc:mysql://mysql:3306/test

Nginx服务

1
docker run --name nginx -p 80:80 -v `pwd`/nginx/html:/usr/share/nginx/html -v `pwd`/nginx/nginx.conf:/etc/nginx/nginx.conf -v `pwd`/nginx/conf.d:/etc/nginx/conf.d -v /etc/localtime:/etc/localtime -v /etc/timezone:/etc/timezone --link tomcat:tomcat -d nginx
/etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
#...
http {
upstream backend {
server tomcat:8080;
}

fastcgi_intercept_errors on;
proxy_intercept_errors on;

include /etc/nginx/conf.d/*.conf;
#...
}
/etc/nginx/conf.d/default.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
#...
location /service/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Remote-Addr $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location ^~ /pic/ {
root /opt/web;
index index.html;

location ~* \.(jpe?g|png|bmp|pdf)$ {
try_files $uri $uri/ /pic/default.png;
}
}
#...
}

嗯,好久好久没有写东西了。下次再讲讲jenkins吧,这个东东解放了好多时间,现在项目中我只是让它自己打包,打包出错时发送邮件。部署的话还没有去实现,主要是现阶段的代码问题太多了。现在还在思考一个问题,是否可以将Docker用于生产环境,然后学习下自己制作Dockerfile,这样我就可以把上面所有的服务打成一个Dockerfile,给别人一个Dockerfile就可以直接用来开发,完全不用自己再去搭环境了。