目录
- 0 专栏介绍
- 1 为什么需要Dockerfile?
- 2 Dockerfile书写原则
- 3 Dockerfile常用指令
- 3.1 `FROM`
- 3.2 MAINTAINER
- 3.3 `RUN`
- 3.4 `ADD`
- 3.5 `COPY`
- 3.6 `CMD`
- 3.7 `ENV`
- 3.8 `EXPOSE`
- 3.9 `WORKDIR`
- 3.10 `ARG`
- 4 Dockerfile构建ROS工程实例
0 专栏介绍
本专栏旨在通过对ROS的系统学习,掌握ROS底层基本分布式原理,并具有机器人建模和应用ROS进行实际项目的开发和调试的工程能力。
🚀详情:《ROS从入门到精通》
1 为什么需要Dockerfile?
Dockerfile
是用来构建Docker
镜像的构建文件,是由一系列命令和参数构成的脚本。详细理解Dockerfile
就是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
Dockerfile
具有很多好处:
- 易于版本化管理:
Dockerfile
本身就是一个文本文件,方便存放在代码仓库中进行版本管理,也方便查找各个版本之间的变更历史。- 无需考虑环境便于构建:使用
Dockerfile
构建镜像不需要考虑构建环境,基于同一个Dockerfile
,无论在哪里运行,构建结果都是一致的。- 过程可追溯:
Dockerfile
中的每一行指令代表一个镜像层, 根据Dockerfile
的内容,可以清晰的查看到镜像的完整构建过程。
2 Dockerfile书写原则
Dockerfile
书写原则如下:
- 单一职责:容器的本质就是一个过程,不同功能的应用程序应该尽可能地划分到不同的容器中,每个容器只负责一个业务流程。
- 保持容器最小化:应该避免安装无用的软件包
- 合理选择基础镜像:容器的核心是应用,所以只要基础镜像可以满足应用的运行环境
尽量使用构建缓存:利用缓存,可以大大缩短镜像构建时间。
最小化镜像层数:在构建镜像时尽可能地减少Dockerfile
指令行数。
3 Dockerfile常用指令
Docker
以从上到下的顺序运行Dockerfile
的指令,本节列出了一些常用的指令。
3.1 FROM
指定基础镜像,必须为第一个命令
-
格式
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
其中
tag
是可选的,如果不使用则采用最新版本的基础镜像 -
例子
FROM osrf/ros:noetic-desktop-full
3.2 MAINTAINER
维护者信息
-
格式
MAINTAINER <name>
-
例子
MAINTAINER Winter
3.3 RUN
用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell
执行- 格式
RUN <shell-command>
- 例子
RUN pip3 install setuptools
- 格式
exec
执行- 格式
RUN ["executable", "param1", "param2"]
- 例子
RUN ["/etc/execfile", "arg1", "arg2"]
- 格式
3.4 ADD
将本地文件添加到容器中,tar
类型文件会自动解压,可以访问网络资源
-
格式
ADD [--chown=<user>:<group>] <src>... <dest>
-
例子
# 相对路径,拷贝到WORKDIR目录下relativeDir/ ADD test.txt relativeDir/ # 绝对路径 ADD test.txt /absoluteDir/ # 更改权限 ADD --chown=55:mygroup files* /somedir/
3.5 COPY
COPY
指令和ADD
指令的唯一区别在于:是否支持从远程URL
获取资源。COPY
指令只能从执行docker build
所在的主机上读取资源并复制到镜像中。相同需求时,推荐使用COPY
指令,ADD
指令更擅长读取本地tar
文件并解压缩或读取远程URL
资源
3.6 CMD
类似于RUN
指令,用于运行程序,但二者运行的时间点不同:CMD
在构建镜像时不会执行,而在容器运行时运行;RUN
则是在docker build
时运行
- 格式
CMD <shell command> CMD [<exe>, <param1>, <param2>, ...] CMD [<param1>, <param2>, ...]
- 例子
每个CMD ["/usr/bin/wc","--help"]
Dockerfile
只能有一条CMD
命令。如果指定了多条命令,只有最后一条会被执行
3.7 ENV
设置环境变量
- 格式
ENV <env_key> <env_val>
- 例子
ENV myName John Doe
3.8 EXPOSE
指定于外界交互的端口
- 格式
EXPOSE <port> [<port>/<protocol>...]
- 例子
该EXPOSE 8080
EXPOSE
指令实际上并未发布端口。要在运行容器时实际发布端口,docker run -P
来发布和映射一个或多个端口
3.9 WORKDIR
工作目录,类似于cd
命令
- 格式
WORKDIR </path/to/workdir>
- 例子
通过WORKDIR /a (这时工作目录为/a)
WORKDIR
设置工作目录后,Dockerfile
中其后的命令RUN
、CMD
、ENTRYPOINT
、ADD
、COPY
等命令都会在该目录下执行
3.10 ARG
定义变量,与ENV
作用相同,不过ARG
变量不会像ENV
变量那样持久化到构建好的镜像中,也就是说只有docker build
的过程中有效。构建命令docker build
中可以用--build-arg <参数名>=<值>
来覆盖。
- 格式
ARG <arg_key>[=<arg_val>]
- 例子
ARG site ARG build_user=www
4 Dockerfile构建ROS工程实例
# Use the official ROS Noetic base image
FROM osrf/ros:noetic-desktop-full
# Set the working directory
WORKDIR /project
# Install additional dependencies if needed
RUN apt-get update \
&& apt-get -y --no-install-recommends install \
git \
gcc \
vim \
psmisc \
libxml2-dev \
libxslt-dev \
python3 \
python3-pip \
python-is-python3\
ros-noetic-amcl \
ros-noetic-base-local-planner \
ros-noetic-map-server \
ros-noetic-move-base \
ros-noetic-navfn
# python packages
RUN pip3 install setuptools && pip3 install catkin-tools
# bash
RUN echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
# Copy the project into the container
COPY . /project
# catkin build
RUN /bin/bash -c '. /opt/ros/noetic/setup.bash; catkin_make'
🔥 更多精彩专栏:
- 《ROS从入门到精通》
- 《机器人原理与技术》
- 《机器学习强基计划》
- 《计算机视觉教程》
- …