一、centos
安装docker
-
1、移除之前的安装的
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 复制代码
-
2、删除文件
rm -rf /etc/systemd/system/docker.service.d rm -rf /var/lib/docker rm -rf /var/run/docker rm -rf /usr/local/docker rm -rf /etc/docker 复制代码
-
3、安装一些必要的系统工具
yum -y install yum-utils device-mapper-persistent-data lvm2 复制代码
-
4、添加软件源信息:
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 复制代码
-
5、更新
yum
缓存:yum makecache fast 复制代码
-
6、安装
Docker-ce
:yum -y install docker-ce 复制代码
-
7、启动 Docker 后台服务:
systemctl start docker 复制代码
-
8、配置哪里的镜像源官网地址
二、docker
中常见的命令
-
1、启动docker
systemctl start docker 复制代码
-
2、停止
docker
systemctl stop docker 复制代码
-
3、重启
docker
systemctl restart docker 复制代码
-
4、查看全部的镜像
docker images docker image ls 复制代码
-
5、查看容器
docker container ps -a docker ps -a 复制代码
-
6、停止全部的容器
docker kill $(docker ps -a -q) 复制代码
-
7、删除全部的容器
docker rm $(docker ps -a -q) 复制代码
-
8、停止容器
docker stop 容器的id 复制代码
-
9、查看容器
docker ps -a 查看全部的容器 docker ps -l 查看最后一个容器 复制代码
-
10、进入一个容器
docker attach 容器id 复制代码
三、启动容器的几种方式
-
1、下载一个容器
docker pull ubuntu 复制代码
-
2、直接运行容器并且输入一句话
docker run ubuntu /bin/echo "Hello world" 复制代码
-
3、以命令行模式进入该容器
docker run -it ubuntu /bin/bash 复制代码
-
4、后台启动一个
nginx
并且对外暴露的端口80映射到主机上的9000上,别名是my_nginx
docker run -d --name my_nginx -p 9000:80 nginx 复制代码
-
5、关于运行的参数说明
NO. 参数 含义 1 -i --interactive 交互式 2 -t --tty 分配一个伪终端 3 -d --detach 运行容器到后台【后台运行】 4 -a --attach list 附加到运行的容器 5 -e --env list 设置容器的变量 6 -p --publish list 发布容器终端到主机【暴露端口】 7 -P --publish-all 8 --mount mount 挂载宿主机分区到容器 9 -v --volumn list 挂载宿主机分区到容器
四、关于数据盘(卷)的认识
-
1、为什么要有数据盘的
删除容器的时候,容器层里创建的文件也会被删除掉,如果有些数据你想永久保存,比如
Web
服务器的日志,数据库管理系统中的数据,可以为容器创建一个数据盘。 -
2、创建数据卷
docker volume --help docker volume create nginx_html # 创建数据卷 docker volume ls # 查看本地创建的数据卷 docker volume inspect nginx_html # 查看数据卷的位置 复制代码
-
3、将本地的数据卷挂载到
nginx
中docker run -d --name my_nginx -p 9000:80 --mount src=nginx_html,dst=/usr/share/nginx/html nginx # 将本地的nginx_html与nginx的容器中的/usr/share/nginx/html中建立关联【我们可以直接在nginx_html的目录下操作容器中的文件】 # 方式二 docker run -d --name my_nginx1 -p 8000:80 -v nginx_html:/usr/share/nginx/html nginx 复制代码
-
4、删除数据卷【先删除容器才可以删除的】
docker volume ls # 查看全部的数据卷 docker volume ls -f dangling=true #列出已经孤立的数据盘 docker stop $(docker ps -a -q) docker rm $(docker ps -a -q) docker volume rm nginx_html 复制代码
-
5、指定文件夹作为数据卷
mkdir ~/data # 本地创建一个文件夹 docker run -v ~/data:/mnt -it --name logs centos bash # 将本地的文件夹data映射到容器中的mnt文件夹并且进入终端 复制代码
五、使用docker
部署应用
部署MySQL
-
1、搜索
mysql
的镜像docker search mysql 复制代码
-
2、下载镜像
docker pull mysql 复制代码
-
3、本地创建文件夹作为数据卷的文件夹
mkdir ~/mysql cd ~/mysql 复制代码
-
4、进入本地数据卷的文件夹下启动容器
docker run -d \ -p 3307:3306 \ --name mysql1 \ -v $PWD/conf:/ect/mysql/conf.d \ -v $PWD/logs:/logs \ -v $PWD/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql 复制代码
- 参数说明
- -p 3307:3306:将容器中的3306端口映射到主键的3307上面
- -v $PWD/conf:/ect/mysql/conf.d :将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
- -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
- -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
- **-e MYSQL_ROOT_PASSWORD=123456:**初始化 root 用户的密码。
- 参数说明
-
5、进入容器中操作
mysql
docker exec –it mysql1 /bin/bash mysql -u root -p 123456 show databases 复制代码
-
6、本地使用
navicat for mysql
连接mysql
发现报错:Client does not support authentication protocol requested by server
-
7、解决方案
-
进入容器
docker exec -it 62349aa31687 /bin/bash 复制代码
-
进入
mysql
mysql -uroot -p 复制代码
-
授权
GRANT ALL ON *.* TO 'root'@'%'; 复制代码
-
刷新授权
flush privileges; 复制代码
-
更新加密规则
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; 复制代码
-
更新
root
用户密码ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; 复制代码
-
刷新权限
flush privileges; 复制代码
-
-
8、本地测试连接
部署nginx
-
1、拉取镜像
docker pull nginx 复制代码
-
2、创建本地数据卷及创建本地的
nginx.conf
的文件mkdir ~/nginx cd ~/nginx mkdir conf cd conf vim nginx.conf 复制代码
-
3、
nginx.conf
的文件内容user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html } } } 复制代码
-
4、进入
~/nginx
的文件夹下启动容器docker run -d \ -p 9000:80 \ --name my_nginx \ -v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \ -v $PWD/logs:/var/log/nginx \ -v $PWD/html:/usr/share/nginx/html \ nginx 复制代码
-
5、进入
~/nginx/html
文件夹下创建并且写入一句话echo index > index.html 复制代码
-
6、直接访问
-
7、如果修改了
nginx
的配置文件,直接重启容器就可以docker restart 容器id 复制代码
部署Redis
-
1、下载镜像
docker pull redis:5.0 复制代码
-
2、创建容器及设置端口的映射
docker run -id --name my_redis -p 6379:6379 redis:5.0 复制代码
-
3、外部连接容器中的
redis
redis-cli -h ip地址 -p 6379 复制代码
-
4、如果在宿主机上要访问
redis
docker exec -it 容器id redis-cli 复制代码
六、Dockerfile
文件的编写
-
1、
docker
的镜像是分层操的docker inspect centos # 查看分层 复制代码
-
2、
dockerfile
文件中命令含义关键字 作用 备注 FROM 指定父镜像 指定dockerfile基于那个image构建 MAINTAINER 作者信息 用来标明这个dockerfile谁写的 LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看 RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"] CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"] ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用 COPY 复制文件 build的时候复制文件到image中 ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数 VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"] EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径 USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户 HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制 ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大 STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。 SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell -
3、
.dockerignore
文件表示要排除,不要打包的
image
中的文件路径
自己动手写一个Dockerfile
文件
-
1、在本地(或者服务器)中安装
node
【使用nvm
方式】 -
2 、安装
express
项目生成器生成一个基础项目npm install express-generator -g express app 复制代码
-
3、在项目的外面创建一个
Dockerfile
的文件touch Dockerfile 复制代码
├── app # 脚手架自动生成的项目文件夹 │ ├── app.js │ ├── bin │ │ └── www │ ├── package.json │ ├── public │ │ ├── images │ │ ├── javascripts │ │ └── stylesheets │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ └── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── Dockerfile # 需要自己写的Dockerfile文件 复制代码
# Dockerfile文件 FROM node COPY ./app /app WORKDIR /app RUN npm install EXPOSE 3000 复制代码
- FROM 表示该镜像继承的镜像 :表示标签
- COPY 是将当前目录下的app目录下面的文件都拷贝到image里的/app目录中
- WORKDIR 指定工作路径,类似于执行
cd
命令 - RUN npm install 在/app目录下安装依赖,安装后的依赖也会打包到image目录中
- EXPOSE 暴露3000端口,允许外部连接这个端口
-
4、创建
image
【需要漫长的等待】docker build -t my_app1 . # -t后面写自己定义镜像的名字 .表示将Dockerfile文件的所有路径 复制代码
-
5、使用镜像生成一个容器
docker run -it -p 3333:3000 my_app1 /bin/bash npm run start 复制代码
-
6、客户端直接访问
-
7、在
Dockerfile
文件中配置CMD
命令在启动容器的时候就运行命令FROM node COPY ./app /app WORKDIR /app RUN npm install CMD npm run start EXPOSE 3000 复制代码
RUN
命令在image
文件的构建阶段执行,执行结果都会打包进入image
文件;CMD
命令则是在容器启动后执行- 一个
Dockerfile
可以包含多个RUN
命令,但是只能有一个CMD
命令 - 指定了
CMD
命令以后,docker container run
命令就不能附加命令了(比如前面的/bin/bas
h),否则它会覆盖CMD
命令
-
8、重新构建成镜像
-
9、创建容器
docker run -d -p 4000:3000 my_app1 复制代码
七、发布自己构建的镜像
-
1、先到官网注册账号
-
2、登录及发布镜像
docker login # 登录hub.docker docker image tag [imageName] [username]/[repository]:[tag] docker image build -t [username]/[repository]:[tag] . docker tag my_app1 kuangshp/my_app1:1.0.0 docker push kuangshp/my_app1:1.0.0 复制代码
八、docker-compose
的使用
-
1、
compose
的作用compose
是通过一个docker-compose.yml
的文件来关联多个docker
的容器(间接意思就是管理多个镜像,毕竟容器是由镜像生成的),在配置文件中,所有容器通过**services
**来定义,然后使用docker-compose
脚本来启动、停止、重启应用(只适合单机版)。主要包括的内容
services
可以定义需要的服务,每个服务都有自己的名字,使用的镜像、挂载的数据卷、网络、依赖别的服务networks
是应用网络volumes
是数据卷,可以在此定义数据卷,然后挂载到不同的服务上面使用。
-
2、安装
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 添加可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 查看版本信息 docker-compose -version # 二进制包方式安装的,删除二进制文件即可 rm /usr/local/bin/docker-compose 复制代码
-
3、
docker-compose.yml
的文件配置- 空格缩进表示层次
- 冒号空格后面有空格
# 模拟写一个docker-compose.yml文件 version: '2' services: name1: image: nginx port: - "8080:80" name2: image: nginx port: - "9000:80" depends_on: # 依赖name1的容器 - name1 name3: image: mysql port: - "3306:3306" networks: # 配置网络 - "networksname" volumes: # 配置数据卷 - db: /var/lib/mysql networks: # 自定义网络别名 networksname: driver: bridge volumes: # 自定义数据卷别名 db: driver: local 复制代码
-
4、常见的
docker-compose
的命令docker-compose up #启动所有的服务 docker-compose -d #后台启动所有的服务 docker-compose ps #打印所有的容器 docker-compose stop #停止所有服务 docker-compose logs -f #持续跟踪日志 docker-compose exec zfpx1 bash #进入zfpx服务系统 docker-compose rm #删除服务容器 docker network ls #网络不会删除 docker-compose down #删除网路 复制代码
九、使用docker-compose
部署项目
项目一(利用前面使用的Dockerfile
打包生成的镜像my_app1
)
-
1、创建一个文件夹里面的文件目录如下
├── docker-compose.yml └── nginx └── conf.d └── test.conf 复制代码
-
2、
docker-compose.yml
的文件内容如下version: "3" services: nginx: image: nginx ports: - 8000:80 # nginx对外访问的端口是8000 links: - app volumes: - ./nginx/conf.d:/etc/nginx/conf.d # 配置数据卷的映射 app: image: my_app1 # 自己build出来的镜像 ports: - 3000:3000 复制代码
-
3、
test.conf
的文件配置反向代理到my_app1
启动的node
项目server { listen 80; # 注意这个地方不是8000 access_log off; location / { proxy_pass http://app:3000; } } 复制代码
-
4、启动
docker-compose.yml up docker-compose.yml up -d # 表示在后台启动,看不到输出日志 复制代码
-
5、启动后查看
docker
启动的容器[root@bogon conf.d]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 566cf1648b5f nginx "nginx -g 'daemon of…" 16 minutes ago Up 11 minutes 0.0.0.0:8000->80/tcp docker_compose_nginx_1 86740bc0bd9e my_app1 "docker-entrypoint.s…" 16 minutes ago Up 11 minutes 0.0.0.0:3000->3000/tcp docker_compose_app_1 复制代码
-
6、浏览器中直接访问8000端口
项目二(不使用本地的镜像,而是直接使用源代码+Dockerfile
文件来构建)
-
1、使用
express
生成的一个app1
的项目,直接在项目外面docker-compose.yml
├── app1 │ ├── app.js │ ├── bin │ │ └── www │ ├── package.json │ ├── public │ │ ├── images │ │ ├── javascripts │ │ └── stylesheets │ │ └── style.css │ ├── routes │ │ ├── index.js │ │ └── users.js │ └── views │ ├── error.jade │ ├── index.jade │ └── layout.jade ├── docker-compose.yml ├── Dockerfile └── nginx └── conf.d └── test.conf 复制代码
-
2、
test.conf
和上面一样的 -
3、
Dockerfile
文件告诉docker
如何来生成一个镜像FROM node COPY ./app1 /app # 把当前的app1文件拷贝到镜像中的app文件夹下 WORKDIR /app RUN npm install CMD npm run start EXPOSE 3000 复制代码
-
4、
docker-compose.yml
来管理nginx
镜像和项目文件version: "3" services: nginx: image: nginx ports: - 8000:80 links: - app volumes: - ./nginx/conf.d:/etc/nginx/conf.d container_name: nginx11 app: build: . ports: - 3000:3000 container_name: app 复制代码
-
5、查看已经启动的容器
[root@bogon docker_compose_test1]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4afdaccab8db nginx "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes 0.0.0.0:8000->80/tcp nginx11 98772bc2f24d docker_compose_test1_app "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:3000->3000/tcp app 复制代码
-
6、在浏览器上直接访问8000端口
项目三
我们希望在
node
中连接mysql
数据库进行增删改查的操作,使用nginx
来处理静态文件资源
-
1、项目的目录结构如下
├── docker-compose.yml └── images ├── mysql ├── nginx │ └── conf.d │ └── test.conf └── node ├── Dockerfile └── web ├── package.json ├── package-lock.json ├── public │ └── index.html └── server.js 复制代码
-
2、在
images/node/web/server.js
中我们创建一个最基本的连接mysql
的命令const http = require('http'); const mysql = require('mysql'); const connection = mysql.createConnection({ host: 'db', user: 'root', password: '123456', database: 'nodeapp' }) http.createServer(function (req, res) { connection.query('select 1 + 1 as total', function (err, results, fields) { if (err) { console.log(err); res.end('error'); } res.end('total' + results[0].total); }) }).listen(8811, () => console.log('服务已经启动:localhost:8811')); 复制代码
-
3、使用命令的方式直接在
public/index.html
中写入内容echo index > index.html 复制代码
-
4、配置
nginx
的配置文件server { listen 80; location / { root /public; index index.html; } location /api { proxy_pass http://node:8811; } } 复制代码
-
5、
Dockerfile
文件编写,将node
项目制做成一个镜像FROM node COPY ./web /web WORKDIR /web RUN npm install CMD npm start 复制代码
-
6、
docker-compose.yml
统一镜像文件编写version: "3" services: db: image: mysql environment: MYSQL_ROOT_PASSWORD: "123456" MYSQL_DATABASE: "nodeapp" volumes: - ./images/mysql/data:/var/lib/mysql - ./images/mysql/conf:/etc/mysql/conf.d - ./images/mysql/logs:/log container_name: nodeapp_db node: build: context: "./images/node" dockerfile: Dockerfile depends_on: - db container_name: nodeapp_node web: image: nginx ports: - 8089:80 # nginx对外的端口是8089 depends_on: - node volumes: - ./images/nginx/conf.d:/etc/nginx/conf.d - ./images/node/web/public:/public container_name: nodeapp_web 复制代码
-
7、使用
docker-compose up
启动工程 -
8、直接在浏览器上输入
localhost:8089
返回的是index
-
9、不出意外的你在浏览器上输入
localhost:8090/api
看docker
的输出日志会报错。原因在于你要先进入mysql
的容器中修改下权限。方法和上面的docker
部署mysql
的解决方案一样的。 -
10、解决上面
mysql
错误的还有一种方案推荐使用-
在
mysql
这个文件夹下创建一个init/init.sql
的文件# cat init/init.sql use mysql; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; # 放开root登入权限 flush privileges; # 刷新 复制代码
-
修改
docker-compose.yml
配置version: "3" services: db: image: mysql environment: MYSQL_ROOT_PASSWORD: "123456" MYSQL_DATABASE: "nodeapp" volumes: - ./images/mysql/data:/var/lib/mysql - ./images/mysql/conf:/etc/mysql/conf.d - ./images/mysql/logs:/log - ./images/mysql/init:/docker-entrypoint-initdb.d # 与之前的配置就添加了这行 container_name: nodeapp_db node: build: context: "./images/node" dockerfile: Dockerfile depends_on: - db container_name: nodeapp_node web: image: nginx ports: - 8089:80 depends_on: - node volumes: - ./images/nginx/conf.d:/etc/nginx/conf.d - ./images/node/web/public:/public 复制代码
-
使用
docker-compose up
启动后,浏览器中输入localhost:8089/api
直接访问不报错了
-