本文介绍如何使用名为的描述文件来自定义Docker映像Dockerfile.
您将看到如何扩展现有映像,根据需要自定义它们,以及如何将生成的映像发布到Docker Hub。
在本教程中,您将学习:
- 如何使用Dockerfile自定义映像。
- 如何在Docker Hub中发布生成的图像。
使用的软件要求和约定
类别 | 使用的要求,约定或软件版本 |
---|---|
系统 | Ubuntu 18.04仿生海狸 |
软件 | 码头工人 |
其他 | 以root身份或通过Linux特权访问Linux系统sudo 命令。 |
约定 | #-要求linux命令可以直接以root用户身份或通过使用root特权以root特权执行sudo 命令$-要求linux命令以普通非特权用户身份执行 |
介绍
之前的文章Docker概念还有一些基本Docker命令。在本文中,您将看到如何自定义和扩展现有的Docker映像,描述Dockerfile中的修改,以及将映像发布到注册表。
Dockerfile
在里面上一篇文章,您已经对正在运行的容器进行了修改,并将所做的更改提交给了本Map像缓存。尽管它是在特定情况下的有用资源,但建议以更具文档化的方式进行自定义,以便可以将映像部署到其他主机。推荐的方法是编写一个Dockerfile。
Dockerfile是一个YAML文件,它是具有某些语法的文本文件:关系使用缩进(空格)表示,并且每一行均由键和值对组成。
让我们从安装软件包的简单Dockerfile开始props
(包含命令htop
和ps
)到Debian图片。
创建一个新目录,进入其中,并使用以下名称保存下面的文件Dockerfile
(大写D):
FROM debian
RUN apt-get update &&\
apt-get -y install procps
该Dockerfile声明基本映像名为Debian(FROM
条款)。如果它在本地不存在,将从Docker Hub下载。的RUN
命令执行apt-get
两次。请注意,使用反斜杠(\)来换行以及使用-y
跳过的确认提示apt-get install
。
下一步是使用docker build
。
$ docker build -t mydebian .
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM debian
---> be2868bebaba
Step 2/2 : RUN apt-get update && apt-get -y install procps
---> Running in 52a16b346afc
…
Removing intermediate container 52a16b346afc
---> f21a05a59966
Successfully built f21a05a59966
Successfully tagged mydebian:latest
旗-t mydebian
正在命名新图像。点(。)告诉docker使用当前目录查找Dockerfile。请注意,随着解释Dockerfile的各行,将创建和删除新层。
本地缓存中必须有一个新映像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mydebian latest f21a05a59966 8 minutes ago 119MB
debian latest be2868bebaba 7 weeks ago 101MB
可以从该图像创建一个容器。
$ docker run -it --name mydebian_container mydebian
root@ef9eb174874a:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 02:43 pts/0 00:00:00 bash
root 9 1 0 02:43 pts/0 00:00:00 ps -ef
从现在开始,您可以使用procps
包和命令htop
和ps
将已经安装。
现在,我们创建一个Dockerfile,在镜像构建时安装Apache和PHP,以实现在容器中执行命令时与上一篇文章相同的目标。
FROM debian
RUN apt-get update &&\
apt-get -y install procps libapache2-mod-php
CMD service apache2 start
我们添加了libapache2-mod-php
在3号线和一个CMD
命令4号线启动Apache。启动容器后,CMD
命令被执行。只能存在一个CMD
每个Dockerfile的命令。当。。。的时候CMD
指定了命令,它将替换CMD
扩展图像的命令。如果CMD
省略命令,将执行基本映像之一(如果有)。您可能已经猜到了,Debian基本映像的Dockerfile有一个CMD
执行bash的命令。您可以在Docker Hub中进行检查。
$ docker run -d --name mydebian_container2 -d -p 8000:80 -v "$PWD":/var/www/html mydebian
ad325685b738464c49bff40b65c6824160105ab5c285282efefbc4ddeec20ba2
roger@slash:~/LinuxConfig/04 Dockerfile$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad325685b738 mydebian "/bin/sh -c 'service…" 11 seconds ago Up 5 seconds 0.0.0.0:8000->80/tcp mydebian_container2
这次我们使用-d
切换,因为我们希望将其与终端分离。
重要的Dockerfile命令
Dockerfile除了其他命令外FROM
,RUN
和CMD
。
命令ENV
用于设置图像中的环境变量,例如http_proxy
, 例如。许多图像使用环境变量将参数传递给新容器。例如,在docker hub中检查MySQL和PostgreSQL等数据库的图像。
命令COPY
在构建时将文件和目录从主机复制到映像。源路径(第一个参数)是相对于当前目录的。
命令ADD
类似于COPY
,不同之处在于,如果源是压缩的tar文件,则它将在映像内的目标目录中自动解压缩。除此用途外,Docker建议使用COPY
尽可能命令。
命令EXPOSE
指示Docker可以公开映像的哪些端口。在容器创建期间,可以根据需要将这些端口映射到主机端口。
命令WORKDIR
设置当在容器内部执行命令时Docker将使用的目录docker exec
。
创建启用了HTTPS的映像
现在,我们将扩展官方的PHP Apache映像,以使用auto-generated证书激活SSL,以举例说明如何使用上述命令。在新目录中,创建以下Dockerfile。
FROM php:7-apache
RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem -subj "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/O=Security/OU=Development/CN=example.com"
RUN a2enmod rewrite
RUN a2ensite default-ssl
RUN a2enmod ssl
EXPOSE 443
COPY ./html /var/www/html
WORKDIR /var/www/html
在3号线我们创建一个证书。第5-7行启用mod_rewrite和SSL。9号线暴露端口443(上游映像已经暴露了端口80)。11号线将应用程序目录添加到容器。最后,13号线将工作目录设置为Apache工作目录。所有命令执行者docker exec
默认情况下将使用此目录作为基础。
现在,创建一个名为html
和一个名为phpinfo.php
与此内容。
<?php
phpinfo();
?>
现在,我们来构建并运行该容器。
docker build -t app_image .
docker run -d --rm -p 80:80 -p 443:443 --name app_container app_image
现在,您可以访问phpinfo.php
通过HTTP和HTTPS编写脚本。
http://localhost/phpinfo.php
https://localhost/phpinfo.php
在HTTPS中,浏览器会抱怨证书的安全性,因为它是self-signed,但是可以忽略该警告。
将映像发布到Docker Hub
创建的图像仅在Docker的本地缓存中本地存在。您可能想要与其他Docker主机或队友共享它们,甚至将它们公开。无论如何,您都想将映像发布到Docker注册表。可以将它们发布到基于云的注册表,例如Docker Hub,顺便说一句,如果您未明确指定注册表,则默认为Docker Hub。第一创建一个免费的Docker ID,然后登录:
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: infroger
Password:
Login Succeeded
接下来,使用存储库名称(infroger),图像名称和标记(图像版本)标记图像。
$ docker tag app_image infroger/app_image:1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
infroger/app_image 1 c093151fc68f 14 hours ago 381MB
app3_image latest c093151fc68f 14 hours ago 381MB
然后将映像推送到存储库。
$ docker push infroger/app_image:1
The push refers to repository [docker.io/infroger/app_image]
27f7f2b01c49: Pushed
81b08cd5fe07: Pushed
d1c23d198f84: Pushed
e66392ad9b85: Pushed
a71f63e3a00f: Pushed
9c58778f21dd: Pushed
973719bed9b7: Pushed
8f5090ef2ac0: Pushed
fbdafdbe3319: Pushed
a5c4801ecf39: Pushed
e9ba112d38b9: Pushed
25ba5230dadf: Pushed
f2907ce42b47: Pushed
e31bf34cfab9: Pushed
9066d03e98e0: Pushed
96db4ce698ad: Pushed
abae6a338e5c: Pushed
4572a80a7a5e: Pushed
ef68f6734aa4: Pushed
1: digest: sha256:2e7e53fcdf800ad0c4837cd70014170cc869d36de5c301f2e2ced318803bf963 size: 4279
现在转到Docker Hub并检查映像是否存在:
https://hub.docker.com/r/infroger/app_image
在免费注册的Docker Hub中,您可以拥有一个私有存储库,并具有无限的公共存储库。否则,您可能要运行您自己的Docker注册表,可以使用以下命令完成:
docker run -d -p 5000:5000 --restart=always --name registry registry:2
拥有私人注册表的好处是隐私。但是您要负担管理安全性,高可用性,存储要求,访问控制等的负担。
结论
在本文中,我们介绍了如何扩展现有图像并使用Dockerfile对其进行自定义。我们还了解了如何将图像发布到Docker注册表。到目前为止,您可以做很多事情,但是我们只是在探讨Docker世界。在下一篇文章中,我们将看到使用Docker Compose进行本地容器编排的一种非常简单的形式。