Dockerfile

Dockerfile

Tim 85 2024-08-23

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明

FROM

定制的镜像都是基于 FROM 的镜像。比如FROM ubuntu就定制需要的基础镜像,后续的操作都是基于ubuntu

RUN

用于执行后面跟着的命令行命令

shell格式

RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。

exec格式

RUN ["可执行文件", "参数1", "参数2"]

# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,使用&& 符号连接命令。

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

  • [--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组

  • <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则

  • <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建

COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]

# COPY metamod.tar.gz /home/steam/metamod-r_i386.tar.gz 

CMD

类似于 RUN 指令,用于运行程序,只不过是在docker run时运行(如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效)

为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

# 推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

ENTRYPOINT

待补充

ENV

设置环境变量。定义了环境变量,那么在后续的指令中就可以使用这个环境变量。

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

# ENV CSPORT=27015
# $CSPORT

VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

  • 避免重要的数据,因容器重启而丢失

  • 避免容器不断变大

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

# VOLUME /home/steam/data 

EXPOSE

仅仅只是声明端口。

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射

  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口

EXPOSE <端口1> [<端口2>...]

# EXPOSE 27015/udp

USER

用于指定执行后续命令的用户和用户组。这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。

USER <用户名>[:<用户组>]

# USER steam:steam

LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式。

LABEL <key>=<value> <key>=<value> <key>=<value> ...

# LABEL description="CS1.6 Image" version="1.8.0815" owner="Tim" create_by="Tim"

构建镜像

docker build -t your-image-name:tag .

# "." 为当前路径

例子

创建CS1.6镜像

# 使用 steamcmd 作为基础镜像
FROM cm2network/steamcmd
#FROM ubuntu

LABEL description="CS1.6 Image" version="1.8.0815" owner="Tim" create_by="Tim"

#环境变量新版要用“=” 并且两边不能有空格
ENV CSPORT=27015
ENV CSMAP=de_dust2
ENV MAXPLAYERS=16

# 设置非交互式安装,避免安装过程中的任何交互提示
ENV DEBIAN_FRONTEND=noninteractive 
  
# 将本地文件metamod、rehlds、amxmodx、regamedll复制到容器中(未取消步骤,但已挂载目录)
COPY metamod.tar.gz /home/steam/metamod-r_i386.tar.gz 
COPY rehlds.tar.gz /home/steam/rehlds_linux.tar.gz 
COPY amxmodx.tar.gz /home/steam/amxmodx.tar.gz
COPY regamedll.tar.gz /home/steam/regamedll.tar.gz
COPY reunion.tar /home/steam/reunion.tar

#创建解压路径
RUN mkdir -p /home/steam/metamod/ && \
    mkdir -p /home/steam/ReHLDS/ && \
    mkdir -p /home/steam/reunion/

#--strip-components=1 是去掉一级目录
# 解压 Metamod-r
RUN tar -xzf /home/steam/metamod-r_i386.tar.gz -C /home/steam/metamod --strip-components=1  && \ 
# 解压 ReHLDS
    tar -xzf /home/steam/rehlds_linux.tar.gz -C /home/steam/ReHLDS --strip-components=1  && \
# 解压 reunion
    tar -xf /home/steam/reunion.tar -C /home/steam/reunion --strip-components=1
 
# 安装 add-apt-repository 命令(software-properties-common 包)
# RUN apt-get update -y && \
#     apt-get install -y software-properties-common && \
#    add-apt-repository multiverse 

#安装steamcmd
#WORKDIR /home/steam/steamcmd/ 
#RUN dpkg --add-architecture i386
#RUN apt-get update -y && \
#    apt-get  install -y lib32gcc-s1 curl && \
#    curl -k -sqL "https://media.st.dl.bscstorage.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf -
 
# 链接环境
WORKDIR /root/.steam
RUN ln -s /home/steam/steamcmd/linux32  sdk32

# 创建工作目录
WORKDIR /home/steam/csserver

# 使用 SteamCMD 下载 CS 1.6
RUN /home/steam/steamcmd/steamcmd.sh \
    +force_install_dir /home/steam/csserver/ \
    +login anonymous \ 
    +app_set_config 90 mod cstrike \
    +quit
#需要两次才能成功
RUN /home/steam/steamcmd/steamcmd.sh \
    +force_install_dir /home/steam/csserver/ \
    +login anonymous \ 
    +app_update 90 -beta steam_legacy validate \
    +quit || true

RUN /home/steam/steamcmd/steamcmd.sh \
    +force_install_dir /home/steam/csserver/ \
    +login anonymous \ 
    +app_update 90 -beta steam_legacy validate \
    +quit 
 
#解压替换regamedll
RUN tar -xzf /home/steam/regamedll.tar.gz -C /home/steam/csserver/cstrike/ --strip-components=1 

#安装metamod
WORKDIR /home/steam/csserver/cstrike/addons/metamod/dlls
RUN cp  /home/steam/metamod/metamod/metamod_i386.so ./metamod.so
#编辑 liblist.gam 配置文件
RUN sed -i 's/gamedll_linux.*/gamedll_linux "addons\/metamod\/dlls\/metamod.so"/' /home/steam/csserver/cstrike/liblist.gam

WORKDIR /home/steam/csserver

#替换rehlds
RUN cp -r /home/steam/ReHLDS/linux32/* ./
#RUN cp -r /home/steam/ReHLDS/linux32/engine_i486.so ./

#安装reunion
RUN cp /home/steam/reunion/reunion.cfg ./ && \
    mkdir -p /home/steam/csserver/cstrike/addons/reunion && \
    cp  /home/steam/reunion/bin/Linux/reunion_mm_i386.so /home/steam/csserver/cstrike/addons/reunion/reunion_mm_i386.so

#安装amxmodx
# 解压安装 AMX Mod X 
RUN tar -xzf /home/steam/amxmodx.tar.gz -C /home/steam/csserver/cstrike/addons/ --strip-components=1    

#挂载amxmodx、挂载reunion
#创建 plugins.ini 文件(如果不存在的话),并添加 AMX Mod X 插件配置
RUN touch ./cstrike/addons/metamod/plugins.ini && \
     echo "linux addons/amxmodx/dlls/amxmodx_mm_i386.so" >> ./cstrike/addons/metamod/plugins.ini && \
     echo "linux addons/reunion/reunion_mm_i386.so" >> ./cstrike/addons/metamod/plugins.ini

#给可执行文件添加执行权限
RUN chmod a+x ./hlds_run ./hlds_linux ./hltv
 
# 编写启动脚本
COPY start_server.sh /home/steam/start_server.sh 

# 暴露端口
EXPOSE ${CSPORT}/udp
  
# 定义卷,用于持久化 CS 1.6 服务器数据 
VOLUME /home/steam/data 
#VOLUME /tmp/

#需要切换root,不换启动脚本里的文件操作没有权限
USER root 
 
# 启动服务器
 CMD ["/home/steam/start_server.sh"]