ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Dockerfile

2021-11-13 17:32:01  阅读:112  来源: 互联网

标签:nginx Dockerfile etc usr mysql docker root


一、什么是dockerfile?

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。

docker build命令用于从Dockerfile构建映像。

#规范:
	Dockerfile命名D必须大写其他必须小写。
	Dockerfile中所有的指令必须大写
			
#构建镜像的命令:
   docker build [OPTIONS] PATH 
#参数:
	-t name:tag : 指定构建镜像的名称

docker build -t nginx:v2 .    # . 当前目录

二、Dockerfile的基本结构

Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,# 为 Dockerfile 中的注释。

一张图解释常用指令的意义:

img

三、Dockerfile文件说明

Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以字符开头则被视为注释。可以在Docker文件中使用RUNCMDFROMEXPOSEENV等指令。

在这里列出了一些常用的指令。

1.FROM:指定基础镜像,必须为第一个命令

#格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

#示例: 
FROM mysql:5.6

#注:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
  

2.MAINTAINER: 维护者信息

#格式:
MAINTAINER <name>

#示例:
MAINTAINER Jasper Xu
MAINTAINER sorex@163.com
MAINTAINER Jasper Xu <sorex@163.com>
    

3.RUN:构建镜像时执行的命令

#RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行

#格式:
RUN <command>
 
#示例:
[root@docker /etc/docker]# cat > Dockerfile << EOF
FROM nginx:1.21.1
RUN touch /usr/share/nginx/1.txt
EOF

[root@docker /etc/docker]# docker build -t nginx:v3 .

[root@docker /etc/docker]# docker run -it --rm nginx:v3 bash
root@8fee06507b90:/# ls /usr/share/nginx/
1.txt  html

#注:运行的命令必须是基础镜像中包含的命令,执行的结果直接保存在景象中

4.ADD

#格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径

#示例:
ADD hom* /mydir/          # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/
    

5.COPY

#功能描述:复制文件到镜像中
#语法:
COPY < src>… < dest>|[“< src>”,… “< dest>”]

#提示:指令逻辑和ADD十分相似,同样Docker Daemon会从编译目录寻找文件或目录,dest为镜像中的绝对路径或者相对于WORKDIR的路径

#示例1:
[root@docker /etc/docker]# ll
-rw-r--r--. 1 root root  67 Oct 22 14:44 daemon.json
-rw-r--r--. 1 root root 101 Nov 11 19:55 Dockerfile
-rw-r--r--. 1 root root 167 Nov 11 19:49 docker.tar.gz
-rw-------. 1 root root 244 Oct 22 14:44 key.json
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1
RUN touch /usr/share/nginx/1.txt
ADD docker.tar.gz /opt
COPY docker.tar.gz /tmp


[root@docker /etc/docker]# docker build -t nginx:v2 .
[root@docker /etc/docker]# docker run -it --rm nginx:v2 bash
root@7034bec837ab:/# ls -l /opt
total 4
-rw-r--r--. 1 root root 52 Nov 11 11:31 Dockerfile
root@7034bec837ab:/# ls -l /tmp
total 4
-rw-r--r--. 1 root root 167 Nov 11 11:49 docker.tar.gz

# ADD 支持自动解压功能,COPY 不支持
# ADD 支持通过URL下载文件(不会自动解压文件),COPY 不支持

#示例2:
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1

ADD https://mirrors.aliyun.com/centos/7.9.2009/extras/x86_64/Packages/etcd-3.2.28-1.el7_8.x86_64.rpm?spm=a2c6h.13651111.0.0.10bd2f70pV7Kl6&file=etcd-3.2.28-1.el7_8.x86_64.rpm /opt

COPY https://mirrors.aliyun.com/centos/7.9.2009/extras/x86_64/Packages/etcd-3.2.28-1.el7_8.x86_64.rpm?spm=a2c6h.13651111.0.0.10bd2f70pV7Kl6&file=etcd-3.2.28-1.el7_8.x86_64.rpm /tmp


[root@docker /etc/docker]# docker build -t nginx:v4 .
-- --- ----- 省略 ------ ------- --------
 ---> 886df84dcc0d
Step 6/6 : COPY https://mirrors.aliyun.com/centos/7.9.2009/extras/x86_64/Packages/etcd-3.2.28-1.el7_8.x86_64.rpm?spm=a2c6h.13651111.0.0.10bd2f70pV7Kl6&file=etcd-3.2.28-1.el7_8.x86_64.rpm /tmp
COPY failed: source can't be a URL for COPY

6.CMD:构建容器后调用,也就是在容器启动时才进行调用

# exec格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)

# shell 格式:
CMD ["param1","param2"] 

#示例1:
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1
CMD ["nginx","-g","daemon off;"]

[root@docker /etc/docker]# docker build -t nginx:v1 .
[root@docker /etc/docker]# docker run -d nginx:v1
54a5e03d4f6f663a5ca40beb4e247d335b95b789bb50218b5c8d14ae401a6bad
[root@docker /etc/docker]# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS     NAMES
54a5e03d4f6f   nginx:v1   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   80/tcp    laughing_easley


#示例2:
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1
CMD nginx -g 'daemon off;'

[root@docker /etc/docker]# docker build -t nginx:v2 .
[root@docker /etc/docker]# docker run -d nginx:v2
[root@docker /etc/docker]# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS     NAMES
adce915fa2a1   nginx:v2   "/docker-entrypoint.…"   4 seconds ago   Up 4 seconds   80/tcp    dreamy_wright


#注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
    

7.ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数

#格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)

#示例:
FROM centos:7
ENTRYPOINT ["ping"]
CMD ["127.0.0.0.1"]

#注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。如果ENTPYPOINT与CMD同时存在,则CMD的相关内容会被设置为ENTPYPOINT的参数

8.LABEL:用于为镜像添加元数据

#格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...

#示例:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"

#注:使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

9.ENV:设置环境变量

#格式:
ENV <key> <value>  #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
    
ENV <key>=<value> ...  #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行

#示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy

10.EXPOSE:指定于外界交互的端口

#格式:
EXPOSE <port> [<port>...]

#示例:
EXPOSE 80 443
EXPOSE 8080    EXPOSE 11211/tcp 11211/udp

#注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
    

11.VOLUME:用于指定持久化目录

#格式:
VOLUME ["/path/to/dir"]

#示例:
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1
VOLUME /usr/share/nginx

[root@docker /etc/docker]# docker build -t nginx:v1 .
[root@docker /etc/docker]# docker run -itd nginx:v1 bash

# VOLUME /usr/share/nginx 在 /var/lib/docker/volumes目录下随机映射
#查看
[root@docker ~]# docker inspect sleepy_wozniak
		"Mounts": [
            {
                "Type": "volume",
                "Name": "462a95793887840bf134192df56117eb2f4ac88e83d80a4e4a99677bf2a4ab98",
                "Source": "/var/lib/docker/volumes/462a95793887840bf134192df56117eb2f4ac88e83d80a4e4a99677bf2a4ab98/_data",
                "Destination": "/usr/share/nginx",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }


#参数:
  -v  :指定挂载目录

#将宿主机的/opt/目录挂载到容器中的/usr/share/nginx
[root@docker /etc/docker]# docker run -itd -v /opt/:/usr/share/nginx nginx:v1 bash
[root@docker ~]# docker exec -it recursing_dijkstra bash
root@c587e91b92be:/# ls -l /usr/share/nginx
total 0
drwx--x--x. 4 root root 28 Oct 22 06:44 containerd
drwxr-xr-x. 2 root root  6 Oct 27 06:31 demo
drwxr-xr-x. 2 root root  6 Oct 25 12:22 html5-mario

#查看
[root@docker ~]# docker inspect recursing_dijkstra
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/opt",
                "Destination": "/usr/share/nginx",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

12.WORKDIR:工作目录,类似于cd命令

#设置工作目录,运行应用程序时的起始目录(默认是根目录)
#格式:
WORKDIR /path/to/workdir

#示例:
[root@docker /etc/docker]# cat Dockerfile 
FROM nginx:1.21.1
VOLUME /usr/share/nginx

[root@docker /etc/docker]# docker build -t nginx:v1 .
[root@docker /etc/docker]# docker run -itd --name nginx01 nginx:v1 bash
[root@docker /etc/docker]# docker exec -it nginx01 bash
root@44c95ab16ca8:/usr/share/nginx# pwd
/usr/share/nginx

#注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。

13.USER

#指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

#格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

#示例:
USER www

#注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过`docker run`运行容器时,可以通过-u参数来覆盖所指定的用户。

14.ARG:用于指定传递给构建运行时的变量

#格式:
ARG <name>[=<default value>]

#示例1:
[root@docker /etc/docker]# cat Dockerfile 
FROM centos:7
ARG PACKAGE=zip
RUN yum install -y $PACKAGE

[root@docker /etc/docker]# docker build -t nginx:v1 .
--- ---- 省略 ---- --- -- 
Installed:
  zip.x86_64 0:3.0-11.el7                                                       

Complete!
Removing intermediate container 29ccd5414e32
 ---> 4890c73d3959
Successfully built 4890c73d3959
Successfully tagged nginx:v1

#示例2:  安装软件自定义
[root@docker /etc/docker]# cat Dockerfile
FROM centos:7
ARG PACKAGE
RUN yum install -y $PACKAGE

[root@docker /etc/docker]# docker build --build-arg=PACKAGE=zsh -t nginx:v2 .
------ ---- 省略 ---- ---- ---
Installed:
  zsh.x86_64 0:5.0.2-34.el7_8.2                                                 

Complete!
Removing intermediate container a98ffcee77e9
 ---> eed93606434c
Successfully built eed93606434c
Successfully tagged nginx:v2
 

15.ONBUILD:用于设置镜像触发器

#格式:
ONBUILD [INSTRUCTION]

#示例:
[root@docker /etc/docker]# cat Dockerfile
FROM centos:7
ONBUILD RUN mkdir /test

[root@docker /etc/docker]# docker build -t nginx:v1 .
[root@af8cd29dcbb2 /]# ls -l | grep test


[root@docker /etc/docker]# cat Dockerfile
FROM nginx:v1
RUN mkdir /old

[root@docker /etc/docker]# docker build -t nginx:v2 .
[root@docker /etc/docker]# docker run -it --rm nginx:v2 bash
[root@fa9f9b35571b /]# ls -l | grep -E "test|old"
drwxr-xr-x.   2 root root     6 Nov 12 08:02 old
drwxr-xr-x.   2 root root     6 Nov 12 08:02 test

#注:ONBUILD后面跟指令,在构建时不会执行。当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被触发

16.使用Dockerfile构建项目

#构建MySQL、PHP以及nginx镜像部署discuz

1.下载MySQL二进制包
#官网二进制包下载地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz
#因为网络问题,我这里是下载的阿里云镜像站的MySQL二进制包
[root@docker /etc/docker]# wget https://mirrors.cloud.tencent.com/mysql/downloads/MySQL-5.7/mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz

2.创建工作目录
[root@docker /etc/docker]# mkdir -p /discuz/mysql
[root@docker /etc/docker]# cd /discuz/mysql
[root@docker /discuz/mysql]# mv /etc/docker/mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz /discuz/mysql

3.配置my.cnf
[root@docker /discuz/mysql]# cat my.cnf 
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/usr/local/mysql/mysql.sock
character-set-server=utf8mb4
log-error=/usr/local/mysql/data/mysqld.log
pid-file=/usr/local/mysql/data/mysqld.pid
[mysql]
socket=/usr/local/mysql/mysql.sock
[client]
socket=/usr/local/mysql/mysql.sock

4.配置构建MySQL的Dockerfile
[root@docker /discuz/mysql]# cat Dockerfile 
FROM centos:7
RUN useradd -M -s /sbin/nologin -r mysql
RUN yum install -y ncurses-devel libaio-devel gcc gcc-c++ numactl libaio glibc cmake autoconf
ADD mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz /usr/local/
RUN ln -s /usr/local/mysql-5.7.36-linux-glibc2.12-x86_64 /usr/local/mysql
RUN chown -R mysql.mysql /usr/local/mysql/
RUN mkdir -p /usr/local/mysql/data
RUN chown -R mysql.mysql /usr/local/mysql/data/
RUN /usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
ADD my.cnf /etc/
WORKDIR /usr/local/mysql/
EXPOSE 3306
CMD /usr/local/mysql/bin/mysqld --user=root --defaults-file=/etc/my.cnf

5.构建镜像
[root@docker /discuz/mysql]# docker build -t mysql:v1 .

6.启动mysql容器测试
[root@docker /discuz/mysql]# docker run -d -P --name=mysql mysql:v1
[root@docker /discuz/mysql]# docker ps
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                    NAMES
d71d0c55967d   mysql:v1   "/bin/sh -c '/usr/lo…"   4 seconds ago   Up 2 seconds   0.0.0.0:4006->3306/tcp   mysql
[root@docker /discuz/mysql]# docker exec -it mysql bash
[root@d71d0c55967d mysql-5.7.36-linux-glibc2.12-x86_64]# ./bin/mysql 
-- 授权
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;
-- 刷新
mysql> FLUSH PRIVILEGES;

#使用Navicat测试连接

6.构建nginx+php镜像
[root@docker /data]# unzip Discuz_X3.4_SC_UTF8_20210926.zip
[root@docker /data]# mv upload /discuz/nginx+php/

#构建镜像
[root@docker /discuz/nginx+php]# cat Dockerfile 
FROM  centos:7
RUN useradd -M -s /sbin/nologin -r www
ADD nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx
RUN sed -i 's#user nginx#user www#g' /etc/nginx/nginx.conf
ADD discuz.conf /etc/nginx/conf.d/
RUN yum remove php-mysql-5.4 php php-fpm php-common
RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
RUN rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
ADD php.repo /etc/yum.repos.d/

RUN yum install -y php72w php72w-cli php72w-common php72w-devel php72w-embedded php72w-gd php72w-mbstring php72w-pdo php72w-xml php72w-fpm php72w-mysqlnd php72w-opcache php72w-pecl-memcached php72w-pecl-redis php72w-pecl-mongodb

RUN sed -i 's#apache#www#g' /etc/php-fpm.d/www.conf
EXPOSE 80 443
CMD php-fpm && nginx -g 'daemon off;'

#启动容器测试
[root@docker /discuz/nginx+php]# docker run -d -P php-nginx:v1
[root@docker /discuz/nginx+php]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                         NAMES
6459eb2c0c5a   php-nginx:v1   "/bin/sh -c 'php-fpm…"   3 seconds ago   Up 2 seconds   0.0.0.0:4052->80/tcp, 0.0.0.0:4051->443/tcp   fervent_robinson

#删除所有测试容器
[root@docker /discuz/nginx+php]# docker rm -f $(docker ps -aq)

#创建dis网桥
[root@docker /discuz/nginx+php]# docker network create dis

#创建容器
[root@docker /discuz/nginx+php]# docker run -d --network dis --name mysql mysql:v1

[root@docker /discuz/nginx+php]# docker run -d --name nginx -p 80:80 --network dis -v /discuz/nginx+php/upload/:/usr/share/nginx/html php-nginx:v1

[root@docker /discuz/nginx+php]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                         NAMES
017a58d6a827   php-nginx:v1   "/bin/sh -c 'php-fpm…"   5 seconds ago        Up 2 seconds        0.0.0.0:80->80/tcp, 443/tcp   nginx
35c458d7c2d3   mysql:v1       "/bin/sh -c '/usr/lo…"   About a minute ago   Up About a minute   3306/tcp                      mysql

#登录到mysql容器中授权
[root@docker /discuz/nginx+php]# docker exec -it mysql bash
[root@35c458d7c2d3 mysql-5.7.36-linux-glibc2.12-x86_64]# ./bin/mysql 
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> create database discuz;

#本地hosts配置
10.0.0.71 linux.discuz.com

#浏览器访问
linux.discuz.com


#文件列表
[root@docker /discuz]# tree -L 2 -C
.
├── mysql
│   ├── Dockerfile
│   ├── my.cnf
│   └── mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz
└── nginx+php
    ├── discuz.conf
    ├── Dockerfile
    ├── nginx.repo
    ├── php.repo
    └── upload

标签:nginx,Dockerfile,etc,usr,mysql,docker,root
来源: https://www.cnblogs.com/backz/p/15549170.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有