FrankKai.github.io
FrankKai.github.io copied to clipboard
docker入门
知道docker这个词已经很久接近2年了,但是一直停留在“知”的层面,最近学习《玩转Spring全家桶》,刚好有一节讲Docker辅助开发,刚好从一台新机器上搭建多依赖的开发环境是一件很棘手的事,因此产生了这个issue。
- 基本命令
- docker run命令详解
- 如何在docker中运行mongodb和redis?
- dockerfile中的sed命令是什么?
- dockerfile中的ln -sv命令是什么?
- Dockerfile中的FROM, COPY, ENTRYPOINT instruction是什么?
- docker中的操作系统镜像怎么玩?
- 如何使用docker跑一个nodejs应用?
- 如何使用docker搭建多语言本地环境?
基本命令
镜像相关
-
docker pull <image>
从registry获取一个image或者repo -
docker search <image>
- docker images 查看本地镜像
- docker rmi IMAGE[:TAG] 删除某个镜像
- docker rm [hash] 删除某个容器
- docker build [OPTIONS] PATH | URL | - 通过Dockerfile构建镜像
- docker image build ./ -t hello-docker:1.0.0 打包镜像(打包好后会出现在docker images中)
- docker container COMMAND 管理镜像
容器相关
- docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- docker start/stop <容器名>
- docker ps <容器名>
- docker logs <容器名>
有用命令
- docker logs mongo 查看镜像运行日志
- docker kill [container id] 根据id杀死某个docker进程
- docker ps -a 查看历史启动过的容器
- docker start [container hash/name] 重启历史容器
docker run命令详解
docker run [OPTIONS] IMAGE [COMMAND][ARG...] 这个命令是用来将image转化成container的。
- -d,后台运行容器
- -e,设置环境变量
- --expose / -p 宿主端口:容器端口
- --name,指定容器名称
- --link,链接不同容器
- -v 宿主目录:容器目录,挂载磁盘卷
docker container命令详解
docker container create -p 2333:80 hello-docker:1.0.0
-p 是 --publish的缩写,打通容器的某个端口到host的端口。
运行了hello-docker:1.0.0镜像的容器,它的80端口打通到宿主机的2333端口,从宿主机的2333可以访问到容器的80端口。
docker container start xxx
启动一个或者多个停止状态的容器。
这里的xxx是docker container create生成的hash值。是容器id。
docker container start 848ea89b9208e3c4e75776aac8410ba54bd414ec4bf2ffb848d1e8812f050082
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
848ea89b9208 hello-docker:1.0.0 "nginx -g 'daemon of…" 2 minutes ago Up 4 seconds 0.0.0.0:2333->80/tcp sleepy_noyce
此时通过lcoalhost:2333可以看到我们容器内80端口的静态页面。
docker container exec -it xxx /bin/bash
exec在一个运行中的container里运行命令。
这里/bin/bash是启动容器内部的/bin/bash,其实也就是进入到了容器内部,通过bash shell与容器交互。
docker container exec -it 848ea89b9208 /bin/bash
root@848ea89b9208:/#
如何在docker中运行mongodb和redis?
docker中运行mongodb
启动mongo容器
docker run --name mongo -d -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin mongo
进入容器bash
docker exec -it mongo bash
登录容器内的mongo
mongo -u admin -p admin
docker中运行redis
docker run --name redis -p 6379:6379 -d redis
进入容器中的redis
docker exec -it redis redis-cli
注意: 1.加上-p及参数后,会将docker容器内的6739端口,映射到本地的6739,也就是0.0.0.0:6739、localhost:6739;若不加,不会打通容器与本机环境
如何在docker中运行mysql?
dockerfile中的sed命令是什么?
介绍
- sed是一个流编辑器(stream editor)。stream editor用来执行基本的文字转换,这个转换是在一个input stream中的(例如:从pipeline里的文件或者input)
- ed命令可以执行类似的操作,但是sed是在众多inputs中,只进行一次传递。
- sed区别于其他stream editor的地方,sed主要在pipeline中过滤text。
基本命令
sed SCRIPT INPUTFILE...
- input.txt的hello全部替换为world
sed 's/hello/world/' input.txt > output.txt
- 未指明INPUTFILE时,会过滤标准输入的内容
cat input.txt | sed 's/hello/world/' - > output.txt
- -i 参数 仅仅编辑输入文件 可以阻止标准文件的输出
sed -i 's/hello/world/' file.txt
- 只打印某些行 使用-n suppress抑制输出 -p打印特定行
sed -n '45p' file.txt // 仅仅打印第45行的内容
- sed把多个文件当做一个长流
sed -n '1p ; $p' one.txt two.txt three.txt //输出第一个文件的第一行 最后一个文件的最后一行
- 可以读写一个sed表达式或文件。通过-e,-f指定表达式或者文件
sed 's/hello/world/' input.txt > output.txt
sed -e 's/hello/world/' input.txt > output.txt
sed --expression='s/hello/world/' input.txt > output.txt
echo 's/hello/world/' > myscript.sed
sed -f myscript.sed input.txt > output.txt
sed --file=myscript.sed input.txt > output.txt
dockerfile中的ln -sv命令是什么?
https://www.geeksforgeeks.org/ln-command-in-linux-with-examples/ ln命令的目的在于在文件间创建link。 如果想搞懂这个ln命令,必须首先搞懂Linux中的hard link和soft link。 [译]Soft and Hard links in Unxi/Linux
-s 创建一个软链接。
-v 显示软链创建指向ln -sv link.js vlink.js //vlink.js -> link.js
Dockerfile中的FROM是什么?
Dockerfile中的FROM是超级重要的。
FROM <image>[:<tag>| @<digest>] [AS <name>]
- FROM instruction 初始化了一个新的构建阶段,为随后的instruction设置了Base Image(An image that has no parent is a base image)。
- 一个有效的Dockerfile必须从FROM指令开始。
- 这里的image可以是任何有效的image-它会从公共的repos拉取镜像。
FROM其实就是为容器的运行设置镜像,设置好后docker会自动拉取这个镜像。
FROM nginx
...
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM nginx
latest: Pulling from library/nginx
b8f262c62ec6: Pull complete
e9218e8f93b1: Pull complete
7acba7289aa3: Pull complete
Digest: sha256:aeded0f2a861747f43a01cf1018cf9efe2bdd02afd57d2b11fcc7fcadc16ccd1
Status: Downloaded newer image for nginx:latest
---> f949e7d76d63
Dockerfile中的COPY是什么?
COPY [--chown=<user>:<group>] <src>...<dest>
COPY instruction从宿主机的<src>
复制新的文件或者目录,添加到容器文件系统的<dest>
路径 。
注意:此处的宿主机是我们自己的机器,非容器。
所以COPY ./index.html /usr/share/nginx/html/index.html
这段代码会将主机当前目录下的index.html添加到容器文件系统的/usr/share/nginx/html
目录下。
Dockerfile中的ENTRYPOINT instruction是什么?
https://docs.docker.com/engine/reference/builder/#entrypoint
两种格式:
- ENTRYPOINT ["executable", "param1", "param2"]
- ENTRYPOIINT command param1 param2
ENTRYPOINT存在的意义在于:配置容器的运行方式。
ENTRYPOINT ["sh", "bin/startSetup.sh"]
shell文件启动容器。
Dockerfile中的EXPOSE是什么?
EXPOSE <port> [<port>/<protocol>...]
- EXPOST instruction 通知Docker容器在运行时监听指定的网络端口。
- 可以指定是TCP或者UDP,默认是TCP。
- EXPOSE实际上并不发布端口。若是要发布,需要通过
docker run -p
指定。
暴露的是宿主机的端口还是容器的端口? 暴露的是容器的80端口,不可能是宿主机的80端口,否则那么多默认的公用一个80端口怎么可能。 再一次证明了容器是一个vm,运行了一个操作系统。所以每一个单独的容器,都会有80,90,8080,8090等等端口。
docker中的操作系统镜像怎么玩?
Ubuntu
拉取ubuntu镜像
docker pull ubuntu
docker pull ubuntu:19.10
运行ubuntu镜像
docker -i -t run ubuntu bash
docker -i -t run ubuntu:19.10 bash
CentOS
同上。
查看CentOS版本:cat /etc/redhat-release
如何使用docker跑一个nodejs应用?
其实只要用node镜像就可以了。
在nodejs app项目中创建一个Dockerfile
// 声明node版本
FROM node:10
// 替换应用的默认端口
EXPOSE 8888
构建并且运行Docker image:
docker build -t my-nodejs-app . // 构建一个名字为my-nodejs-app的镜像;.表示在当前目录。
docker run -it --rm --name my-running-app my-nodejs-app // 运行my-nodejs-app镜像运行容器,并且命名为my-running-app ,与此同时打开一个可交互的terminal。
思考:
- -it是什么意思?
The -it instructs Docker to allocate a pseudo-TTY connected to the container’s stdin; creating an interactive bash shell in the container. -it表示Docker会分配一个与容器的stdin连接的伪TTY;并且在容器内创建一个可交互的bash shell。
-i --interactive 即使不能连接也会让STDIN开启;-t tty分配一个伪tty
其实说白了就是开启新的伪termina
2.TTY是什么?
终端设备。
通过tty命令可以查看当前的tty。tty // /dev/ttys003
3.--rm 当容器存在时,自动移除容器。
4.--name 为容器分配一个名字。
https://nodejs.org/en/docs/guides/nodejs-docker-webapp/
如何使用docker搭建多语言本地环境?
例如java,nodejs,golang,dart,python等等,只要直接拉取镜像,然后运行起来就可以了。
这个问题从本质上就不成立,因为镜像是用来跑应用跑应用跑应用的。