Docker安装常用软件
在之前的学笔记中,我们已经学习了Docker的基础知识和理论。这里我们记录一下Docker安装常用软件,方便后续直接复制使用。
注意:在这里大多数容器我没有带上
--restart=always
,所以可能会出现宿主机重启后,docker启动了但是很多容器没有启动的情况,这里附上命令:
- docker启动所有容器:
docker start $(docker ps -a | awk '{ print $1}' | tail -n +2)
- docker关闭所有容器:
docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
- docker删除所有容器:
docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)
- docker删除所有镜像:
docker rmi $(docker p_w_picpaths | awk '{print $3}' |tail -n +2)
其中
tail -n +2
表示从第二行开始读取。还有,删除容器的同时要删除挂载数据卷的话:
docker rm -v 容器名
Docker安装MySQL
这里我们以安装MySQL5.7版本为例。
首先docker pull
拉取镜像:
1 | docker pull mysql:5.7 |
接下来docker run
启动容器:
1 | docker run -d --name mysql5 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name mysql5
:为该容器指定名称为mysql5-p 3308:3306
:端口映射(主机(宿主)端口:容器端口),即宿主机开放出3308端口,指向容器内的3306端口-v /home/root/dockerVolumes/mysql/mysql5.7:/var/lib/mysql
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/var/lib/mysql
挂载到宿主机的/home/root/dockerVolumes/mysql/mysql5.7
文件夹下
- 注意:如果我们要命名数据卷中对应宿主机的文件名,比如命名为mysql-db,则可以这么写:
-v mysql-db: /home/root/dockerVolumes/mysql/mysql5.7:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=1234
:设置环境变量,在这里我们设置mysql的root用户密码为1234
进入MySQL容器内:docker exec -it mysql5 bash
Docker安装MongoDB
这里我们以安装MongoDB5.0版本为例。
首先docker pull
拉取镜像:
1 | docker pull mongo:5.0 |
接下来docker run
启动容器:
1 | docker run -d --name mongodb5 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name mongodb5
:为该容器指定名称为mongodb5-p 27017:27017
:端口映射(主机(宿主)端口:容器端口),即宿主机开放出27017端口,指向容器内的27017端口-v /home/root/dockerVolumes/mongo/mongo5.0:/data/db
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/data/db
挂载到宿主机的/home/root/dockerVolumes/mongo/mongo5.0
文件夹下-e MONGO_INITDB_ROOT_USERNAME=root
:设置环境变量,在这里我们设置MongoDB的root用户-e MONGO_INITDB_ROOT_PASSWORD=1234 --privileged=true
:设置环境变量,root用户密码为1234。privileged=true
使得容器内的root拥有真正的root权限
进入MongoDB 容器内:docker exec -it mongodb5 bash
(这里推荐直接进入MangoDB进行操作:docker exec -it mongodb5 mongo
(进入bash之后面对的是一个linux系统))
Docker安装Redis
这里我们以Redis-6.2.3-buster版本为例。
首先docker pull
拉取镜像:
1 | docker pull redis:6.2.3-buster |
接下来docker run
启动容器:
1 | docker run -d --name redis6 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name redis6
:为该容器指定名称为redis6-p 6379:6379
:端口映射(主机(宿主)端口:容器端口),即宿主机开放出6379端口,指向容器内的6379端口-v /home/root/dockerVolumes/redis/redis6.2.3-buster/data:/data
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/data
挂载到宿主机的/home/root/dockerVolumes/redis/redis6.2.3-buster/data
文件夹下,另一个同理redis-server /usr/local/etc/redis/redis.conf --appendonly yes
:这里并不是参数OPTIONS而是COMMAND:
/usr/local/etc/redis/redis.conf
:以配置文件启动redis,加载容器内的conf文件(因为我们配置了数据卷,最终找到的是挂载的目录/home/root/dockerVolumes/redis/redis6.2.3-buster/redis.conf
)
- 注意:docker镜像reids默认无配置文件启动
--appendonly yes
:开启持久化(AOF方式,Redis持久化)
- 如果要在docker run时添加redis密码:只需要在末尾处,加上
--requirepass "mypassword"
- docker run之后设置(修改)密码:
- 进入redis的容器:
docker exec -it redis6 redis-cli
(直接进入redis客户端)- 查看现有的redis密码:
config get requirepass
- 设置redis密码:
config set requirepass yourpassword
进入Redis容器内:docker exec -it redis6 redis-cli
(直接进入redis客户端,docker exec -it redis6 bash
进入到的是linux系统内,此时要进入redis客户端还要额外执行redis-cli
)
运行之后我们本地的/home/root/dockerVolumes/redis/redis6.2.3-buster/redis.conf
下是没有redis.conf文件的(redis.conf官网下载)
我们需要在这里创建一个redis.conf文件(vim redis.conf
),在原有文件(原有文件可从官网下载)的基础上修改如下:
1 | bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问 |
我们可以测试一下:进入容器,输入redis-cli
,然后输入set name rick
:
然后在宿主机的/home/root/dockerVolumes/redis/redis6.2.3-buster/data
(容器中的/usr/local/etc/redis/redis.conf
就是挂载在这个文件夹下)中,查看appendonly.aof文件如下:
Docker安装Elasticsearch
推荐使用docker compose安装。(使用Docker-Compose部署单节点ELK)
这里以安装elasticsearch:6.4.0版本为例。
创建网关
因为ES和Kibana建议以一个独立的服务存在,所以这里我们给ES和Kibana单独创建一个network:
1 | docker network create es-net |
可以通过
docker network ls
命令查看所以的network。
安装elasticsearch
首先docker pull
拉取镜像:
1 | docker pull elasticsearch:6.4.0 |
接下来docker run
启动容器(直接这样可能会报错,看下面的新方法!):
1 | docker run -d --name es6 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name es6
:为该容器指定名称为es6--network es-net
:指定network(注意指定的network要与安装Kibana时指定的network一样)-p 9200:9200 -p 9300:9300
:端口映射(主机(宿主)端口:容器端口)。即宿主机开放出9200端口,指向容器内的9200端口;宿主机开放出9300端口,指向容器内的9300端口(9200:Web端口,与RESTful客户端通信;9300:为TCP端口,与Java做通信)-v /home/root/dockerVolumes/es/es6.4.0/data:/usr/share/elasticsearch/data
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/usr/share/elasticsearch/data
挂载到宿主机的/home/root/dockerVolumes/es/es6.4.0/data
文件夹下(ES在Docker中的所有数据都存储在容器中的/usr/share/elasticsearch/data
中)-v /home/root/dockerVolumes/es/es6.4.0/config:/usr/share/elasticsearch/config
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/usr/share/elasticsearch/config
挂载到宿主机的/home/root/dockerVolumes/es/es6.4.0/config
文件夹下(ES在Docker中的所有配置都存储在容器中的/usr/share/elasticsearch/config
中)-e "discovery.type=single-node"
:设置环境变量,表示ES以单节点模式启动(虽然名为单节点,但是还是以集群模式启动。所以不加这个参数,默认集群启动,也没有问题)-e ES_JAVA_OPTS="-Xms512m -Xmx512m"
:设置环境变量,设置JVM参数(如果启动不了,可以添加此参数加大内存设置)
这样启动会发现启动失败,查询日志发现:
docker启动elasticsearch异常java.nio.file.NoSuchFileException
解决办法:先将挂载数据卷配置注释,启动elasticsearch后将elasticsearch容器中的config/文件夹下的文件拷出到宿主机,重新启动即可。
即新的运行方法为:
先不加-v
参数进行运行容器:
1 | docker run -d --name es6 \ |
然后将容器内的数据拷贝到宿主机:
1 | docker cp es6:/usr/share/elasticsearch/config /home/root/dockerVolumes/es/es6.4.0/ |
此时可以发现宿主机下的config文件夹下已经有文件了:
此时删除容器:
1 | docker stop es6 |
这里记得先修改一下宿主机挂载目录的权限,不然会报错:
1 | chmod 777 /home/root/dockerVolumes/es/es6.4.0/ |
应该只需要执行
chmod 777 /home/root/dockerVolumes/es/es6.4.0/data
就行的。如果不修改宿主机目录权限会报错:
然后再完整的运行一次容器:
1 | docker run -d --name es6 \ |
进入elasticsearch容器内:docker exec -it es6 /bin/bash
。
可以发现目录结构如下:
目录 | 配置文件 | 描述 |
---|---|---|
bin | 脚本文件,包括启动 Elasticsearch、安装插件,运行统计数据等。 | |
config | elasticsearch.yml | 集群配置文件 |
JDK | Java 运行环境 | |
data | path.data | 数据文件 |
lib | Java 类库 | |
logs | path.logs | 日志文件 |
modules | 包含所有 ES 模块 | |
plugins | 包含所有已安装插件 |
安装IK分词器
插件安装可以用elasticsearch-plugin install url
命令。比如安装:elasticsearch-analysis-ik
(分词器),Ik分词器版本要和ES和Kibana版本保持一致。
进入容器内:docker exec -it es6 /bin/bash
plugins安装步骤:
- 进入plugins文件夹:
cd /usr/share/elasticsearch/plugins/
- 安装插件,elasticsearch-analysis-ik版本与elasticsearch保持一致,即
6.4.0
:elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.0/elasticsearch-analysis-ik-6.4.0.zip
- 退出容器:
exit
- 重启docker容器:
docker restart es6
分词器使用验证
ik_smart
:智能分词,最少切分,宁缺毋滥,保证查准率ik_max_word
:最大化分词法,最细粒度划分,尽量多的有意义的分词,保证查全率。ik_max_word
分词包含ik_smart
Postman post请求分词测试:http://ip:9200/_analyze
安装kibana
kibana
和elasticsearch
的版本必须保持严格一致。
首先docker pull
拉取镜像:
1 | docker pull kibana:6.4.0 |
接下来docker run
启动容器:
1 | docker run -d --name kibana6 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name kibana6
:为该容器指定名称为kibana6--network es-net
:指定network(注意指定的network要与安装elasticsearch时指定的network一样)-e ELASTICSEARCH_URL=http://es6:9200
:设置环境变量,让kibana能连接到elasticsearch(es6为上面我们创建elasticsearch时取的容器名,9200为创建elasticsearch容器时宿主机对应的容器内9200端口)
进入kibana容器内:docker exec -it kibana6 bash
访问http://ip:5601
就可以访问到kibana的界面了。
注意:在将elk从6升级到7时,遇到了一些问题。Kibana server is not ready yet
在这里我是这样解决的:
参考这个回答:
进入kibana7容器内
docker exec -it kibana7 bash
:修改
/usr/share/kibana/config
下的kibana.yml
文件,体现在:elasticsearch.hosts: [ "http://宿主机ip:9200" ]
这样就成功解决问题。
安装elasticsearch-head
elasticsearch-head
是用于Elasticsearch监控的插件。
首先docker pull
拉取镜像:
1 | docker pull mobz/elasticsearch-head:5 |
接下来docker run
启动容器:
1 | docker run -d --name es-head5 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name es-head5
:为该容器指定名称为es-head5-p 9100:9100
:端口映射(主机(宿主)端口:容器端口),即宿主机开放出9100端口,指向容器内的9100端口
进入elasticsearch-head容器内:docker exec -it es-head5 bash
浏览器访问:http://ip:9100/
。如下:
当输入 http://ip:9200/
点击连接时,会发现无法连接。是因为前后端分离开发,存在跨域问题,需要在服务端做 CORS 的配置。
由于我们进行过数据卷挂载,不需要进入elasticsearch容器内部,直接在宿主机的/home/root/dockerVolumes/es/es6.4.0/config
下修改elasticsearch.yml
配置。
输入vim elasticsearch.yml
,添加如下两条配置,注意冒号后面有空格,保存并退出。
1 | http.cors.enabled: true |
重启容器:docker restart es6
此时输入 http://ip:9200/
点击连接就可以连接到了:
Docker安装RabbitMQ
这里我们以安装rabbitmq 3.8-management版本为例。
带有mangement的版本包含web管理页面。
首先docker pull
拉取镜像:
1 | docker pull rabbitmq:3.8-management |
接下来docker run
启动容器:
1 | docker run -d --name rabbitmq3.8 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name rabbitmq3.8
:为该容器指定名称为rabbitmq3.8-p 5672:5672 -p 15672:15672
:端口映射(主机(宿主)端口:容器端口)
- 5672:应用访问端口
- 15672:控制台Web端口号
-v /home/root/dockerVolumes/rabbit/rabbit3.8/data:/var/lib/rabbitmq
:绑定数据卷(/宿主机绝对路径目录:/容器内目录),将容器内的/var/lib/rabbitmq
挂载到宿主机的/home/root/dockerVolumes/rabbit/rabbit3.8/data
文件夹下--hostname myrabbit
:指定主机名(RabbitMQ的一个重要注意事项是它根据所谓的节点名称存储数据,默认为主机名)-e
设置环境变量:
-e RABBITMQ_DEFAULT_VHOST=my_vhost
:默认虚拟机名为my_vhost-e RABBITMQ_DEFAULT_USER=admin
:默认用户名为admin-e RABBITMQ_DEFAULT_PASS=admin
:默认用户admin的密码为admin
进入rabbit容器内:docker exec -it rabbitmq3.8 bash
运行后访问http://ip:15672/
,进入rabbit的web管理界面。
Docker安装Tomcat
这里我们以tomcat-8.5.66-jdk8-openjdk-buster版本为例。
首先docker pull
拉取镜像:
1 | docker pull tomcat:8.5.66-jdk8-openjdk-buster |
接下来docker run
启动容器:
1 | docker run -d --name tomcat8 \ |
参数说明:
-d
:后台运行容器,并返回容器ID--name tomcat8
:为该容器指定名称为tomcat8-p 8888:8080
:端口映射(主机(宿主)端口:容器端口),即宿主机开放出8888端口,指向容器内的8080端口(特殊情况需要绑定数据卷的话,再根据情况添加
-v
参数即可)
注意:这里有一个坑,这在之前的笔记中我们已经解决过了,并且将解决后的容器docker commit
成了一个新的镜像,这里再简单记录一下:
在这里我们直接访问http://192.168.219.101:8888/
是这样的:
我们进入到正在运行的tomcat容器中,输入:
1 | docker exec -it tomcat8 bash |
然后我们将空的webapps文件夹删掉,并将webapps.dist改名为webapps即可,输入命令:
1 | rm -rf webapps |
然后我们在访问http://192.168.219.101:8888/
就ok啦:
当然这种方法只是解决了我们当前容器的问题,如果想一劳永逸,我们可以把当前正在运行的正常容器docker commit
到本地成为一个新的镜像,后续需要使用的时候直接docker run
即可;或者我们也可以通过DockerFile来docker build
一个镜像,这在之前的笔记也都提到过了(docker commit方法,DockerFile方法)
安装Docker compose V2
在ubuntu上的安装Docker compose V2:
1 | sudo apt update |
查看已运行的容器的docker run启动参数
命令很简单:docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike 容器名
如:
1 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike mysql5 |
1 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike redis6 |