前端 Docker 基本教程
为什么要学习 Docker ?
每学一个东西,我们肯定是基于某个需求去学习的,众所周知,软件开发最麻烦的是环境配置,开发好好的,部署出问题就很难受,所以为了确保开发、测试、部署环境一致,且高效的部署所以选择了容器技术而非 VM ,而 Docker 是基于 Linux 容器技术的开源项目,它的口头禅就是:“一次构建,处处运行”,具有轻量,速度,社区活跃,且拓展性高。
安装
点我进入官网安装
Docker 支持 Linux、Mac、 Window,直接去官网下载安装就行了
快速开始
学习新的技术都需要一个 Hello World,让我们快速开始体验一下 Docker
直接进入终端开始吧!
# 拉取nginx镜像
docker pull nginx
# 创建一个nginx容器
docker run -d --name test-nginx -p 3000:80 nginx
然后打开 localhost:3000 即可访问到熟悉的 nginx 页面了
是不是非常简单?那我们接下来具体说一说 Docker 的组成
镜像 image
镜像是一个二进制文件,里面具有应用程序以及依赖,只有通过它,Docker 才能够生成容器,相当于模具一样,同一个镜像文件可以生成多个容器实例
对于如何制作镜像,一般来说我们都是通过加工别人基础镜像来生成我们自己的镜像,而不是从零开始,而且我们也可以在这里共享我们的镜像,这也是我们选择它的理由之一,我们可以享受社区的贡献
镜像常用的命令
# 列出本机的所有 image 文件。
$ docker image ls
# 拉取镜像
$ docker pull [imageName]
# 删除 image 文件
$ docker image rm [imageName]
用 Dockerfile 构建一个镜像
在前面我们已经使用过nginx的镜像了,这次我们尝试用 Dockerfile 构建一个自己的镜像
新建一个 docker-test 文件夹,在里面新建一个index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello World</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
然后新建一个 Dockerfile 文件
# 声明基于 nginx 最新的镜像 这里说一下镜像名:后面的是标签 默认是latest
FROM nginx:latest
# 把刚才 index.html 复制到 nginx 的 html 路径去
COPY index.html /usr/share/nginx/html/index.html
# 声明暴露80端口
EXPOSE 80
运行命令
# 生成一个名为 nginx 标签为0.0.1 的镜像 ,注意最后还有一个 .
docker image build -t nginx:0.0.1 .
# 根据刚生成的镜像 启动容器
docker run -d --name test-nginx1 -p 3001:80 nginx:0.0.1
这时候再次访问 locahost:3001 已经不是默认的 nginx 的访问页面了
这里解释一下参数
- -p 参数是指容器的 80 端口映射到本机的 3001 端口
- -d 守护式运行(适合运行应用程序和服务)
- --name 容器名称 如果不指定则是一个随机的名称
容器 container
容器常用的命令
# 查看正在运行的容器
docker ps
# 查看所有创建过的容器(运行或者关闭)
docker ps -a
# 停止容器
docker stop [container]
# 启动容器
docker start [container]
# 删除容器
docker rm [container]
# 查看后台运行的日志
docker logs [containe]
可以先用这些容器命令操作一下我们之前创建的容器,尝试一下
那么在上一节我们自己构建了一个镜像代替了 nginx 的默认页面,那如果我们还想改怎么办?除了新构建一个镜像之外,我们还可以直接进入容器里进行修改
docker container exec -it [containe] /bin/bash
这样就进去了容器的 shell ,可以随意进行操作,当然就算你误操作比如运行了经典的了,也没有关系
在这里我们是使用了 -it 这个参数 它和 -d 区别就在于
-d => 使用 pm2 start index.js
-it => 使用 node.js
当然,真正开发的时候,肯定不可能是这样去修改了,好比之前的端口映射,也可以将容器的内部的目录也映射出来实现共共享,这就是接下来要说的 Volume
数据卷 Volume
回到我们 docker-test 文件夹,然后重新启动一个nginx容器(这里使用的端口和容器名与快速开始的创建的容器相同,请同学们复习一下容器命令先自行删除再创建)
docker run -d --name test-nginx -v $PWD/index.html:/usr/share/nginx/html/index.html -p 3000:80 nginx
我们打开 locahost:3000 修改一下 index.html 的内容为 Hello Volume ,刷新一下网页即可看到我们修改的内容
在这里
很容易发现我们和之前的区别就是使用了 -v参数 本地路径:容器路径 通过这样进行映射,这样当我们修改本地的文件的时候就等于修改了容器内的文件
那么就当在一个项目中,nginx部署好了前端,那么我们需要一个服务提供数据,在 docker-test 的文件夹下面
创建一个 mysql 文件夹 在mysql文件夹中创建一个data存储数据,创建一个my.cnf用作配置
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
启动容器
docker run --name test-mysql -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v $PWD/mysql/my.cnf:/etc/mysql/my.cnf -v $PWD/mysql/data:/var/lib/mysql -d mysql
然后我们通过上一节学会的命令进入 test-mysql 容器中创建数据库以及创建表 加插入一条数据
docker container exec -it test-mysql /bin/bash
# 下面是 test-mysql 容器中的 shell
# 登陆 输入密码
mysql -u root -p
# 创建数据库 test
create databse test;
# 进入 test 数据库
use test;
# 进入 PEOPLE 数据表 字段为 name age
Create Table PEOPLE (name VARCHAR(20), age CHAR(20));
# 插入一行数据到 PEOPLE
Insert into PEOPLE Values('kdq', '24')
然后我们退出容器,再 docker-test 下创建一个文件夹 node ,并创建一个 index.js 文件
const http = require("http");
const mysql = require("mysql");
const connection = mysql.createConnection({
host: "test-mysql",
user: "root",
password: "root",
database: "test"
});
connection.connect();
const server = http.createServer().listen(3001);
server.on("request", (req, res) => {
if (/testapi/.test(req.url)) {
try {
var sqlstr = "Select * From PEOPLE";
connection.query(sqlstr, function(err, result) {
if (err) {
console.log("SELECT ", err.message);
return;
}
res.end(JSON.stringify(result));
});
} catch (error) {
res.end("404 not found");
}
} else {
res.end("404 not found");
}
});
然后启动容器
docker run -it --name test-node -v $PWD/node:/var/www/node -v $PWD/mysql/data:/var/lib/mysql -p 3001:3001 node /bin/bash
# 下面是 test-node 容器中的 shell
cd /var/www/node
node index.js
我们发现 mysql 的操作报错了 connect ECONNREFUSED 127.0.0.1:3306 ,原来是因为我们的 mysql 和 node 是两个容器,而容器是相互隔离的,无法 ping 通
那么难道我们得把 mysql 和 node 都得部署在一个容器里?其实 Docker 更建议一个容器做一件事情,而这种理念其实在我们的开发中也是随处可见的,所以 Docker 可以使用 Networking 进行通信
网络 Networking
首先创建一个网络
docker network create test-net
然后把上一节启动 test-mysql 和 test-node 的容器的命令改成
# test-mysql
docker run --name test-mysql -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v $PWD/mysql:/etc/mysql --network test-net -d mysql
# test-node
docker run -it --name test-node -v $PWD/node:/var/www/node --network test-net -p 3001:3001 node /bin/bash
这时候我们在 node 的 index.js 中修改一下连接 mysql 的 host
const connection = mysql.createConnection({
host: "test-mysql",
user: "root",
password: "root",
database: "test"
});
然后我们启动一下 node 服务 访问 localhost:3001/testapi 就能看到我们查询到的数据了
那么我们也可以将 nginx 加入 test-net 网络中互相通信,具体就留给你们自己去做了
组合 docker-compose
经过上一节我们发现启动容器要输入这么多参数,而且多个容器服务就要启动多次,不仅繁琐,还容易出错
我们可以写 Dockerfile 写一层层命令来构建镜像,是不是也可以用一个配置去启动容器?
答案是可以的,这时候就需要 docker-compose ,当然,如果你的 docker 安装的时候自带就不用再次安装了,具体可以观看文档 点我下载
安装之后 在我们的 docker-test 文件夹下新建一个 docker-compose.yml
version: "3.7"
services:
test-mysql:
image: mysql
volumes:
- ./mysql/my.cnf:/etc/mysql/my.cnf
- ./mysql/data:/var/lib/mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=root
networks:
- test-net
test-node:
image: node
volumes:
- ./node:/var/www/node
ports:
- 3001:3001
command:
- /bin/bash
- -c
- |
cd /var/www/node
node index.js
tail -f /dev/null
networks:
- test-net
depends_on:
- test-mysql
test-nginx:
image: nginx
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/index.html:/usr/share/nginx/html/index.html
ports:
- 3000:80
networks:
- test-net
depends_on:
- test-node
networks:
test-net:
driver: bridge
目前的 docker-test 情况
|-- mysql
|-- data
|-- my.cnf
|-- nginx
|-- index.html
|-- nginx.conf
|-- node
|-- node_modules
|-- index.js
|-- package.json
|-- package-lock.json
|-- docker-compose.yml
通过 docker-compose 启动容器(先把之前启动的三个容器关了)
docker-compose up -d
打开 localhost:3001/testapi 发现依然查询到了数据,就这样一个简单的项目环境准备好了
总结
简单的介绍一下如何使用Docker以及基本的命令,相信大家已经对 Docker 有所了解,对于相关配置想知道更多的可以查看官网文档,如果想看书的同学,可以看第一本Docker书
前端 Docker 基本教程的更多相关文章
- [转帖]Docker 入门教程
Docker 入门教程 http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html 自己学的还是太肤浅啊.. 作者: 阮一峰 日期: 201 ...
- Docker简明教程
Docker简明教程 [编者的话]使用Docker来写代码更高效并能有效提升自己的技能.Docker能打包你的开发环境,消除包的依赖冲突,并通过集装箱式的应用来减少开发时间和学习时间. Docker作 ...
- Docker入门教程(九)10个镜像相关的API
Docker入门教程(九)10个镜像相关的API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第九篇,重点介绍了镜像相关的Docker Remote ...
- Docker入门教程(八)Docker Remote API
Docker入门教程(八)Docker Remote API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第八篇,重点介绍了Docker Remote ...
- Docker入门教程(七)Docker API
Docker入门教程(七)Docker API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第七篇,重点介绍了Docker Registry API和 ...
- Docker入门教程(六)另外的15个Docker命令
Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...
- Docker入门教程(五)Docker安全
Docker入门教程(五)Docker安全 [编者的话]DockOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第五篇,介绍了Docker的安全问题,依然是老话重谈,入门者可以通 ...
- Docker入门教程(四)Docker Registry
Docker入门教程(四)Docker Registry [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第四篇,介绍了Docker Registry,它 ...
- Docker入门教程(三)Dockerfile
Docker入门教程(三)Dockerfile [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第三篇,介绍了Dockerfile的语法,DockerOn ...
随机推荐
- 异步查询转同步加redis业务实现的BUG分享
在最近的性能测试中,某一个查询接口指标不通过,开发做了N次优化,最终的优化方案如下:异步查询然后转同步,再加上redis缓存.此为背景. 在测试过程中发现一个BUG:同样的请求在第一次查询结果是OK的 ...
- Rainbow Plan团队项目第一次作业——项目计划
团队项目--Rainbow Plan英语学习App 1.团队简介 1.1团队名称:Rainbow Plan (彩虹计划) 1.2团队成员: 队员学号 队员姓名 201731024235 何继武(组长) ...
- Liunx创建到部署ASP.NET Core项目从零开始-----使用Centos7
一.搭建环境 1..注册Microsoft密钥和源 执行命令:sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages ...
- C语言 获取系统时间与睡眠时间函数
摘要: 以ms为单位,获取系统时间.睡眠或延迟时间函数的使用方法. #include<stdio.h> #include <time.h> #include <sys/t ...
- Docker获取镜像报错docker: Error response from daemon
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled ...
- 基于 Istio 与 Kubernetes 对应用进行灰度发布与 Tracing
灰度发布,是指在黑与白之间,能够平滑过渡的一种发布方式.通俗来说,即让产品的迭代能够按照不同的灰度策略对新版本进行线上环境的测试,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以对新版本进行测试 ...
- Centos7 下搭建STF平台
STF,全名Smartphone Test Farm---智能手机测试平台,可以提供远程真机调试的功能,目前仅支持Android设备. 环境准备 1.Node.js 8 安装Node.js $ cur ...
- 在Anaconda3下安装(CPU版)TensorFlow(清华镜像源)
1.打开Anaconda Prompt 2.搭建TensorFlow的环境: conda config --add channels https://mirrors.tuna.tsinghua.edu ...
- k8s-dashboard的部署与卸载
相对于枯燥的命令行管理,控制台的管理方式相对就显得更加直观便捷了,虽然官方的dashboard有点不太好用,但是作为免费的dashaboard还是可以体验一番的,下面开始部署这个难用的dashboar ...
- ubuntu系统下安装pip3及第三方库的安装
ubuntu系统下会自带python2.x和python3.x坏境,不需要我们去安装.并且ubuntu系统下还会自动帮助我们安装python2.x坏境下的pip安装工具, 但是没有python3.x坏 ...