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写就行

posted @ 2024-06-27 14:45  colorfullbz  阅读(98)  评论(0)    收藏  举报