Docker学习
常用命令
docker ps -a 查看所有容器
docker stop id 停止一个容器
docker rm ID 删除一个容器(先停在删)
$抓取镜像
docker pull tutum/lamp
docker pull huamang/testdocker
docker pull dongyu29/dongyu29
library是 image 文件所在的组,hello-world是 image 文件的名字。Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略
$列出当前镜像
docker image ls
$列出本机正在运行的容器
docker container ls
$运行镜像
docker create -p 1234:80 --name game tutum/lamp !!!
docker start game !!!
docker container run hello-world
docker run -p 1234:80 --name game tutum/lamp
docker container run命令会从 image 文件,生成一个正在运行的容器实例。注意,docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的docker image pull命令并不是必需的步骤。
$安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。
docker container run -it ubuntu bash
$手动终止容器运行
docker container kill [containID]
$image 文件生成的容器实例,本身也是一个文件,称为容器文件。
也就是说,一旦容器生成,就会同时存在两个文件:
image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。
docker container rm [containerID]
$生成容器
docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
$退出容器
在容器的命令行,按下 Ctrl + c 停止 Node 进程,
然后按下 Ctrl + d (或者输入 exit)退出容器。
此外,也可以用docker container kill终止容器运行。
$在容器终止运行后自动删除容器文件。
docker container run --rm -p 8000:3000 -it koa-demo /bin/bash
$其他
前面的docker container run命令是新建容器,每运行一次,就会新建一个容器。
如果希望重复使用容器,就要使用docker container start命令
docker container start [containerID]
前面的docker container kill就会强行立即终止,那些正在进行中的操作会全部丢失。
应用程序收到stop以后,可以自行进行收尾清理工作
docker container stop [containerID]
portainer-ce
中文图形化管理界面
安装
docker pull portainer/portainer-ce
启动
docker run -d -p 9000:9000 –restart=always -v /var/run/docker.sock:/var/run/docker.sock –name my-portainer portainer/portainer-ce:latest
参数说明:
-d:后台启动
-p:端口映射
–restart=always:开启自启动
-v:数据卷映射
–name:容器名称
提交镜像
自己制作image文件需要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。
先登录:
docker login
登录完后,把所需上传的容器变为镜像
docker commit containerId dockerUserName/XXX
docker commit 7c94bbb39f40ebcfa41cf09 dongyu29/dongy
注:containerId为你需要上传的容器id,可以用docker ps -aqf “name=web9"进行查询容器id
dockerUserName为dockerHub的登录名,xxx为仓库名,当然也不一定非得是dockerUserName/xxx,只是为了方便起见
docker tag imageName dockerUserName/xxx[:tag]
docker tag awd12 dongyu29/awd:plus
docker push dongyu29/awd:plu
注:imageName为你需要上传的镜像name,dockerUserName为dockerHub的登录名,xxx为仓库名,必须和你在dockerhub中新建的仓库名相同,tag不指定就是latest
docker push dockerUserName/xxx[:tag]
dockerfile
Docker可以使用Dockerfile的内容来自动构建镜像。Dockerfile也是一个文件,其中有创建镜像、运行指令等一系列的命令,且每行只支持一个运行命令。
Docker file分为四部分组成:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
常用命令
FROM
用来指定基础镜像,然后通过在基础镜像上构建新的镜像,Dockerfile文件第一行必须的FROM指令,如果一个Dockerfile需要创建多个镜像,可以使用多个FROM指令。
MAINTAINER
指定镜像的创建者信息
RUN
运行所有基础镜像能支持的命令,同样也可以使用多条RUN指令,可以使用\来换行
CMD
用于==容器启动==时的指定操作,它可以是命令,也可以是脚本,但只执行一次
EXPOSE
指定容器暴漏的端口(EXPOSE 80)
ENV
在镜像中用于设置环境变量
COPY
复制本地主机的源(默认为==Dockerfile所在的目录==)到容器中的目标中,目标路径不存在时会自动创建。路径必须是绝对路径
执行dockerfile
docker build -t <镜像名> .
docker run -d -p 1234:80 <镜像名>
docker build -t hihi .
docker run -d -p 1888:80 -p 1889:22 awd12
实践
FROM tutum/lamp
RUN cd /var/www/ && \
rm -rf html && \
mkdir html && \
chown -R root:root /var/www/html/ && \
chmod -R 755 /var/www/html/
COPY src /var/www/html/
EXPOSE 80
成功
docker-compose
用一个
Dockerfile
模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器
Compose
恰好满足了这样的需求。它允许用户通过一个单独的docker-compose.yml
模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
https://yeasy.gitbook.io/docker_practice/compose
例子
version: "3"
services:
db:
image: postgres
environment:
- FLAG=flag{test_flag}
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
容器的启动也可以根据已有的镜像,如果定义了image这个标签,就会从本地搜寻相关镜像构建容器,如果本地找不到相关的镜像,就会从网上数据库搜寻相关的镜像。但大家可能会产生疑问了,这里我们定义了build还有image两个不同的标签来构建镜像,那么容器到底要用build还是image来构建呢,这种情况下将==按照dockerfile的方式来构建镜像,并且把镜像的名称定义为image标签里面的名称==。
version: “3"不变
services:不变,下面是构成这个项目的几个子容器,首行缩进控制好,类似于python,这个例子就有db和web两个子容器
子容器中:
image指定使用的镜像,当然,完全可以不指定,只指定dockerfile的路径,在dockerfile里面指定
build指定dockerfile的路径
ports指定端口映射
运行
docker-compose up -d
停止
docker-compose down
本地镜像
https://www.jianshu.com/p/8c40e2d78e1b
docker save -o [导出的镜像名.tar] [本地镜像名]:[镜像标签]
docker load -i [本地tar包文件]
CTF出题
dockerfile
可以用这个镜像为基础
FROM ctftraining/base_image_nginx_mysql_php_56
COPY src /var/www/html
RUN mv /var/www/html/flag.sh / \
&& chmod +x /flag.sh
docker-compose.yml
version: "2"
services:
web:
build: .
image: ctftraining/0ctf_2016_unserialize
environment:
- FLAG=flag{test_flag}
ports:
- "0.0.0.0:1949:80"
docker-compose up -d就可以在1949端口看到题目了
从上面的过程中,我们看到对于一道题目来说,除了源码以外,最大的不方便之处就是还要有相关的nginx文件配置,在这里我推荐virink写的base_image_nginx_mysql_php_56来辅助我们快速出题。 这个镜像主要好在不需要我们去配置其他的nginx设置,而且还支持自动导入db.sql文件,支持自动执行flag.sh文件。以我在minil出的一道题为例。题目中主要是需要配置数据库. 我们只需要src文件夹中放入源码、flag.sh、db.sql(flag.sh、db.sql文件名不能变),现在我们dockerfile只需要这么写:
FROM ctftraining/base_image_nginx_mysql_php_56
COPY src /var/www/html
RUN mv /var/www/html/flag.sh / \
&& chmod +x /flag.sh
这个镜像就会自动为我们配置相关的nginx文件,同时自动导入要执行的db.sql文件来配置数据库(==默认用户为root,密码也为root,执行后db.sql会被删掉==) 同时镜像还会自动执行flag.sh来从环境变量中读取flag写入到flag.php中(需要注意的是,flag.sh必需在根目录下,也就是我们需要执行mv /var/www/html/flag.sh /这一步的原因所在)。 可以看到,这个镜像极大的方便了我们对Dockerfile的编写,把Dockerfile简化到只需要两三句话就能搞定。 如果是要在php7的环境下出题,可以采用base_image_nginx_mysql_php_73
ctftraining/base_image_nginx_mysql_php_56
ctftraining/base_image_nginx_mysql_php_73
docker run -p 1238:80 –name iii ctftraining/base_image_nginx_mysql_php_56
连接docker容器
docker container ls
docker exec -it <容器id> /bin/bash
docker exec -it awd /bin/bash