<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/ DTD/wml_1.1.xml">

<wml>
<head>
<meta http-equiv="cache-control" content="max-age=180,private" />
</head>
<card title="Dockerfile简单定制自己的镜像">
<p>
作者:<a href="index.php?action=showuser&amp;userid=1&amp;hash=">admin</a><br />时间:2023-11-12 20:28<br />分类:<a href="index.php?action=list&amp;cid=3&amp;hash=">电脑技术</a><br />内容:
Dockerfile简单定制自己的镜像




遇到问题：


Ubuntu/Debian docker中无法使用systemctl，无法实现容器启动后自动启动ssh服务。


当需要使用最新版的Centos，Ubuntu，Debian镜像时候发现几个问题


因为需要宿主机的权限，并且可以使用systemctl，必须加上 -privileged=true 和 /usr/sbin/init 参数，Centos默认集成了init，可以正常运行，但是Ubuntu/Debian只要带上 /sbin/init 就提示出错 ，原因是默认系统已经不在集成init了，需要自己手动安装，但是手动安装麻烦，不能实现自己安装程序自启动，所以最好能够集成到镜像中，要不就使用三方镜像，不过三方集成软件不一定是自己需要的，所以最好是自己定制镜像。定制镜像还可以实现常用软件的集成，系统密码的定制等个性化服务。




小常识：




XML/HTML代码


    /usr/sbin/init 启动容器之后可以使用systemctl方法

    -privileged=true 获取宿主机root权限（特殊权限-）

    su命令和su -命令最大的本质区别就是：前者只是切换了root身份，但Shell环境仍然是普通用户的Shell；而后者连用户和Shell环境一起切换成root身份了。




解决方法：


新的debian和ubuntu镜像中移除了init软件包，如果需要在debian/ubuntu的docker容器中使用systemctl命令，需要修改官方镜像， 创建一个Dockerfile:




XML/HTML代码


    nano Dockerfile

    #填入以下内容并保存

    FROM ubuntu:20.04

    RUN apt-get update &amp;&amp; apt-get install -y init &amp;&amp; apt-get clean all

    #另外我还希望创建的镜像能够安装ssh并允许密码登录

    RUN apt-get update &amp;&amp; apt-get install -y openssh-server nano lsof

    RUN mkdir /var/run/sshd

    RUN echo 'root:password' | chpasswd

    RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

    RUN /usr/sbin/sshd -D &amp;

    EXPOSE 22





XML/HTML代码


    #构建镜像

    docker build -f ./Dockerfile . -t my/ubuntu

    #启动容器

    docker run -tid --name ubuntu -p 2222:22 --privileged=true my/ubuntu /sbin/init




之后发现在容器中可以使用systemctl了，并且可以直接使用ssh服务了。


如果需要集成其他的软件包，可以自行修改添加 apt-get install 后面的包名。


如果是debian或者alpine之类的其他系统也是一样，手动修改dockerfile文件即可。


比如Deiban最新版本


Dockerfile




XML/HTML代码


    FROM debian:latest

    RUN apt-get update &amp;&amp; apt-get install -y init &amp;&amp; apt-get clean all

    RUN apt-get update &amp;&amp; apt-get install -y openssh-server nano lsof htop nload ncdu wget curl  tar gzip  bzip2 xz-utils  unzip net-tools

    RUN mkdir /var/run/sshd

    RUN echo 'root:password' | chpasswd

    RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

    RUN /usr/sbin/sshd -D &amp;

    EXPOSE 22







alpine集成ssh




Dockerfile




XML/HTML代码


    FROM alpine:latest

    # 替换阿里云的并更新源、安装openssh 并修改配置文件和生成key 并且同步时间

    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \

        &amp;&amp; apk update \

        &amp;&amp; apk add --no-cache openssh tzdata bash\

        &amp;&amp; cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \

        &amp;&amp; sed -i &quot;s/#PermitRootLogin.*/PermitRootLogin yes/g&quot; /etc/ssh/sshd_config \

        &amp;&amp; ssh-keygen -t dsa -P &quot;&quot; -f /etc/ssh/ssh_host_dsa_key \

        &amp;&amp; ssh-keygen -t rsa -P &quot;&quot; -f /etc/ssh/ssh_host_rsa_key \

        &amp;&amp; ssh-keygen -t ecdsa -P &quot;&quot; -f /etc/ssh/ssh_host_ecdsa_key \

        &amp;&amp; ssh-keygen -t ed25519 -P &quot;&quot; -f /etc/ssh/ssh_host_ed25519_key \

        &amp;&amp; echo &quot;root:123456&quot; | chpasswd \

        &amp;&amp; rm -rf /var/lib/apt/lists/* \

        &amp;&amp; rm /var/cache/apk/*

     

    EXPOSE 22

     

    CMD [&quot;/usr/sbin/sshd&quot;, &quot;-D&quot;]







参考：


官方镜像版本 关于常用镜像 其他1 其他2 其他3


通过以上操作可以在本地建立一个自己的镜像，但是只要换机器都要重新操作比较麻烦，可以给镜像上传到自己的dockerhub仓库，以后直接docker pull下载就行，也可以方便的分享给他人。




上传镜像到 docker hub 中


1. 申请 Docker hub 账号


首先在 https://hub.docker.com 官网申请一个 docker hub 帐号, 该账号是免费申请的。


2. 创建个人仓库


create -&gt; create repository  （例如ID是 charleswan 仓库是 gfwlist2privoxy）


3. 创建镜像


在本地这里使用 Dockerfile 的方式建立一个 image。


通过 docker build 生成一个新的镜像, -t 可以指定新镜像的名字, . 表示在当前目录下




XML/HTML代码


    docker build -t charleswan/gfwlist2privoxy .







接下来可以 docker images 查看本地镜像。


4. 给镜像打标签


查看本地镜像




XML/HTML代码


    docker image ls







修改标签语法: docker tag IMAGEID(镜像 id) REPOSITORY:TAG(仓库: 标签)


tag 如果不指定默认为 latest。




XML/HTML代码


    docker tag 2657f9dbbd15 charleswan/gfwlist2privoxy:1.0.3

    docker tag 2657f9dbbd15 charleswan/gfwlist2privoxy   # 不指定 tag 默认为 latest, 每次提交前一定要这样写, 否则你的镜像将没有 latest, 其他人拉取的时候必须要指定 tag 才能 pull







5. push 镜像


#修改本地镜像tag为要上传的dockerhub的tag，然后上传




XML/HTML代码


    docker tag local-image:tagname new-repo:tagname

    docker push new-repo:tagname







5.1. 登录 docker hub 账号


docker login


保存身份密钥的路径一般在 ~/.docker 下。


5.2. push 镜像


语法: docker push &lt;hub-user&gt;/&lt;repo-name&gt;:&lt;tag&gt;




XML/HTML代码


    docker push charleswan/gfwlist2privoxy:1.0.3

    docker push charleswan/gfwlist2privoxy    # 提交 latest







Push 成功之后, 可登录到 https://hub.docker.com 网站, 查看一下刚才创建的仓库名称。


或者, 使用 docker search 命令查找。




XML/HTML代码


    docker search gfwlist2privoxy




通过以上操作，就可以给镜像托管到dockerhub仓库，不管是公开还是私有，都可以方便的在任何地方直接下载使用。




</p><p>
<a href="index.php?action=login&amp;hash=">立即登陆发表评论</a><br />
</p>
<p><a href="index.php?action=list&amp;hash=">返回日志列表</a><br /><a href="index.php?action=index&amp;hash=">返回主页</a></p>
</card>
</wml>
