一、本篇侧重点
- 数据卷容器
- Docker的具名挂载、匿名挂载、指定路径挂载
- Dockerfile
- Dockerfile指令说明
- 实战:Dockerfile构建带http-flv模块的nginx镜像
二、数据卷容器
- 话不多说先上图!
就是将服务器上的某个文件夹的绝对路径与Docker实例上某个路径做映射,挂载到实例上,这样实例就能访问服务器的真实文件夹,总结一句话:容器的持久化和同步操作!容器间是可以数据共享。
- 挂载命令:-v, –volume
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口 镜像名称
提前准备好一个nginx.conf文件,放到这个文件夹/usr/local/docker/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;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
启动一个nginx,并挂载目录/usr/local/docker/nginx/conf
docker run -it --name mynginx -v /usr/local/docker/nginx/conf:/etc/nginx/ -p 8001:80 nginx
# 进入容器
docker exec -it f4e5cdcc3576 /bin/bash
可以看到文件已经挂载上来了,然后在服务器上添加一个文件加入内容,再到docker实例内部查看:
- 使用 docker inspect 容器id 查看详情:
docker inspect f4e5cdcc3576
上图中 Mounts 便是这个容器的挂载配置,注:它是一个数组,可以同时挂载多个目录!
三、Docker的具名、匿名、指定路径挂载
- 匿名挂载
# -v 容器内路径
docker run -d -P --name mynginx1 -v /etc/nginx nginx
# 查看所有的volume的情况
docker volume ls
这种就是匿名挂载,不指定宿主机的任何路径
# 使用命令查看容器的匿名挂载情况
docker volume inspect 6f743944485ff33375f3a0699c3a0c90da3273b8c48826e33f1ab134e25a3e4e
匿名挂载时,Docker会在宿主机固定目录为容器挂载一个目录,根目录在:/var/lib/docker/volumes/ 下,然后 加上容器id/_data 这个目录就是容器的数据目录
- 具名挂载
# -v 名字:容器内路径
docker run -d -P --name mynginx1 -v/etc/nginx nginx
# 使用命令查看挂载情况
docker volume inspect juming_nginx
所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data下!
- 指定路径挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
- 拓展
# 通过 -v 容器内路径: ro rw 改变读写权限
# ro #readonly 只读
# rw #readwrite 可读可写
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
四、Dockerfile
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层!
构建步骤:
编写一个dockerfile文件
docker build 构建称为一个镜像
docker run运行镜像
docker push发布镜像(DockerHub 、阿里云仓库)
DockerFile的构建过程
基础知识:
每个保留关键字(指令)都是必须是大写字母
执行从上到下顺序
#表示注释
每一个指令都会创建提交一个新的镜像曾,并提交!
Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行产品。
Docker容器:容器就是镜像运行起来提供服务。
五、Dockerfile指令说明
FROM # from:基础镜像,一切从这里开始构建
MAINTAINER # maintainer:镜像是谁写的, 姓名+邮箱
RUN # run:镜像构建的时候需要运行的命令
ADD # add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # workdir:镜像的工作目录
VOLUME # volume:挂载的目录
EXPOSE # expose:保留端口配置
CMD # cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,触发指令
COPY # copy:类似ADD,将我们文件拷贝到镜像中
ENV # env:构建的时候设置环境变量!
六、 实战:Dockerfile构建带http-flv模块的nginx镜像
现在公司产品需求需要做视频监控功能,也是第一次做,真的是一边踩坑一边收资料然后还要狂补H5播放、码流转码,流服务器这一类的知识,真的是太难了!用nginx也可以做流媒体服务器,但是它需要继承一个第三方模块http-flv,docker里面又只提供了基础的nginx镜像,无法满足,决定手动编译一个带http-flv模块的nginx,然后打包成docker镜像!
话不多说开始撸起来!
首选准备nginx源码包、http-flv模块的源码包(github上可下载),解压!
# 进入到nginx1.18目录下,对nginx进行编译
bash configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/lock/nginx.lock --user=root --group=root --with-http_ssl_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-debug --http-client-body-temp-path=/usr/local/nginx/temp --with-stream --without-http_rewrite_module --add-module=../nginx-http-flv-module-1.2.9
# 最后的 --add-module=../nginx-http-flv-module-1.2.9 增加http-flv模块
# 编译
make
# 输出文件
make install
/usr/local/nginx 此目录就是编译后的nginx目录
# 切换到 /usr/local 目录 编写一个dockerfile,内容如下:
FROM centos
MAINTAINER cyh
WORKDIR /usr/local
# 将宿主机当前目录下的nginx 复制到 镜像内的/usr/local/nginx/下
COPY nginx /usr/local/nginx/
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
# 使用命令创建镜像 不要忘记后面的点!!!
# -f 可指定dockerfile文件
# -t 镜像名
docker build -t nginx_stream:1.0 .
# 导出镜像成一个tar文件
docker save -o nginx_stream.tar nginx_stream:1.0
# 为什么要导出成文件,因为我是在家里制作的镜像文件呀,等周一带到公司就可以部署了!啊哈哈哈哈哈
启动docker镜像成一个容器!
docker run -d --name nginx_stream -p 8081:80 -v /usr/local/nginx/conf:/usr/local/nginx/conf -v /usr/local/nginx/html:/usr/local/nginx/html -v /usr/local/nginx/logs:/usr/local/nginx/logs nginx_stream:1.0
# 这里挂载了3个目录 分别是配置文件目录,静态文件目录和日志目录,方便配置和管理!
接下来咱们修改宿主机/usr/local/nginx/html/index.html文件,将title标题改成hello!http-flv!然后重启docker容器,在访问8081,看看挂载是否成功!
在贴一份作为流媒体服务器的nginx.conf的配置,日后写视频监控的记录时会用到!
worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
application live {
live on;
hls on;
hls_path temp/hls;
hls_fragment 1s;
hls_cleanup on;
hls_playlist_length 1s;
}
application hls {
live on;
hls on;
hls_fragment 8s;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
access_log off;
server {
listen 20000;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
#为了能访问到hls流协议新增:
location /hls {
types{
applictaion/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root html;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location /live {
flv_live on;
chunked_transfer_encoding on; #open 'Transfer-Encoding: chunked' response
add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header 'Cache-Control' 'no-cache';
}
}
}