Docker dockerfile 编写
Docker是用go语言写的开源项目,在Linux的LXC容器基础上进一步封装的,是CS架构的,其目标是实现轻量级的操作系统虚拟化解决方案.
自己创建docker的时候需要有一个名叫dockerfile的文件以及其他的源文件.
dockerfile 的基础命令
FROM
指明构建的新镜像是来自于哪个基础镜像,如果没有选择tag,那么默认值为latest.
FROM python
如果不以任何镜像为基础,那么写法为:FROM scratch.官方说明:scratch镜像是一个空镜像,可以用于构建busybox等超小镜像,可以说是真正的从零开始构建属于自己的镜像.
LABEL
为镜像指定标签,可以用来标识功能或作者
LABEL maintainer="xxxx.com"
RUN
构建镜像的时候使用的bash命令,比如:
RUN pip install flask
ADD
拷贝文件或目录到镜像中.src 可以是一个本地文件或者是一个本地压缩文件,压缩文件会自动解压.
还可以是一个url,如果把src写成一个url,那么ADD就类似于wget命令,然后自动下载和解压.
ADD app.py /app/
COPY
拷贝文件或目录到镜像中.用法同 ADD,只是不支持自动下载和解压.
COPY app.py /app/
EXPOSE
暴露容器运行时的监听端口给外部,可以指定端口是监听TCP还是UDP,如果未指定协议,则默认为TCP.
EXPOSE 80 443 8080/tcp
如果想使得容器与宿主机的端口有映射关系,必须在容器启动的时候加上 -P参数.
ENV
用于设置容器内环境变量.ENV ...添加单个,ENV= ...添加多个
ENV FLAG TSCTF-J{wo_you_zui}
CMD
实例化容器的时候执行的命令,只能实现一个,如果有多个的话以最后一个为准.语法:
CMD["param1","param2"],比如:CMD["echo","$JAVA_HOME"]
CMD command param1 param2,比如:CMD echo $JAVA_HOME
CMD ["python3","app.py"]
可被docker run时指定的参数覆盖.
ENTRYPOINT
和CMD作用相同,但是不能被docker run时指定的参数进行覆盖.如果和CMD同时存在的话以最后一个出现的标准.
ENTRYPOINT ["python3","app.py"]
总而言之就是实例化容器的时候只能执行一条命令
WORKDIR
为RUN,CMD,ENTRYPOINT以及COPY和AND设置工作目录.
WORKDIR /app
构建容器
上学期学过相应的命令
sudo docker build -t <image_name> .
sudo docker run -d -p <linux_port>:<docker_port> <image_id>
需要注意的是源码中设置的暴露的端口,和dockerfile中暴露的端口,实例化时映射的端口应该相统一.
实战演练
通过搭建一道前两天学习的CTF中的SSTI的题目来进行具体的学习
首先准备后app.py源文件如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, render_template, render_template_string, redirect, request, session, abort, send_from_directory
app = Flask(__name__)
@app.route("/")
def index():
def safe_jinja(s):
blacklist = ['class', 'attr', 'mro', 'base', 'request', 'session', '+', 'add', 'chr', 'ord', 'redirect', 'url_for', 'config', 'builtins', 'get_flashed_messages', 'get', 'subclasses', 'form', 'cookies', 'headers', '[', ']', '\'', '"', '{}']
flag = True
for no in blacklist:
if no.lower() in s.lower():
flag = False
break
return flag
if not request.args.get('name'):
return open(__file__).read()
elif safe_jinja(request.args.get('name')):
name = request.args.get('name')
else:
name = 'wendell'
template = '''
<div class="center-content">
<p>Hello, %s</p>
</div>
<!--flag in /flag-->
<!--python3.8-->
''' % (name)
return render_template_string(template)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
然后准备一个dockerfile文件如下
FROM python:latest
WORKDIR /app
RUN pip install flask
COPY app.py /app/
EXPOSE 5000
CMD ['python3','app.py']
由于环境非常的简单,所以dockerfile也比较的简短
然后使用下面的命令运行容器
sudo docker build -t ssti:1.0 .
sudo docker run -d -p 1111:5000 <image_id>
通过ivp6地址即可远程访问了.经过测试能够成功的打通,但是fenjing跑不出来.
docker-compose.yml
如果我们需要将我们的docker部署到服务器中,那么就需要一个docker-compose.yml
就比如说下面的
version: '18.04' #依赖的镜像的版本
services: #服务名
ctf_service: #容器名
build: #使用dockerfile构建镜像时的属性
context: . #当前目录
dockerfile: Dockerfile #dockerfile文件名
ports:
- "8080:9999" #端口映射
volumes:
- ./src:/home/ctf/src #挂载的目录
restart: unless-stopped #重启相关
实际上,只要写好了dockerfile,那么dockercompose让gpt写就行

浙公网安备 33010602011771号