FrankKai.github.io icon indicating copy to clipboard operation
FrankKai.github.io copied to clipboard

docker入门

Open FrankKai opened this issue 5 years ago • 9 comments

知道docker这个词已经很久接近2年了,但是一直停留在“知”的层面,最近学习《玩转Spring全家桶》,刚好有一节讲Docker辅助开发,刚好从一台新机器上搭建多依赖的开发环境是一件很棘手的事,因此产生了这个issue。

  • 基本命令
  • docker run命令详解
  • 如何在docker中运行mongodb和redis?
  • dockerfile中的sed命令是什么?
  • dockerfile中的ln -sv命令是什么?
  • Dockerfile中的FROM, COPY, ENTRYPOINT instruction是什么?
  • docker中的操作系统镜像怎么玩?
  • 如何使用docker跑一个nodejs应用?
  • 如何使用docker搭建多语言本地环境?

FrankKai avatar Apr 10 '19 09:04 FrankKai

基本命令

镜像相关

  • 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] 重启历史容器

FrankKai avatar Apr 10 '19 09:04 FrankKai

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端口的静态页面。 image docker container exec -it xxx /bin/bash exec在一个运行中的container里运行命令。 这里/bin/bash是启动容器内部的/bin/bash,其实也就是进入到了容器内部,通过bash shell与容器交互。

docker container exec -it 848ea89b9208 /bin/bash
root@848ea89b9208:/# 

FrankKai avatar Apr 10 '19 09:04 FrankKai

如何在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?

FrankKai avatar May 09 '19 02:05 FrankKai

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

FrankKai avatar Aug 30 '19 14:08 FrankKai

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

FrankKai avatar Aug 31 '19 13:08 FrankKai

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等等端口。

FrankKai avatar Sep 04 '19 09:09 FrankKai

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

FrankKai avatar Oct 03 '19 07:10 FrankKai

如何使用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。

思考:

  1. -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/

FrankKai avatar Oct 03 '19 07:10 FrankKai

如何使用docker搭建多语言本地环境?

例如java,nodejs,golang,dart,python等等,只要直接拉取镜像,然后运行起来就可以了。

这个问题从本质上就不成立,因为镜像是用来跑应用跑应用跑应用的。

FrankKai avatar Oct 11 '19 02:10 FrankKai