介绍
Dockerfile 是用于定义 Docker 容器镜像的文件。它包含了一系列指令,这些指令告诉 Docker 如何构建一个新的镜像。下面是对 Dockerfile 及其常用指令的简单介绍:
Dockerfile 基础
-
FROM:指定基础镜像。每个 Dockerfile 都必须以这个指令开始。例如:
FROM ubuntu:20.04
-
MAINTAINER:指定维护者信息(已被 LABEL 替代,但仍被很多 Dockerfile 使用)。例如:
MAINTAINER yourname@example.com
-
RUN:在镜像内执行命令。通常用于安装软件包。例如:
RUN apt-get update && apt-get install -y nginx
-
COPY:将本地文件复制到镜像内。例如:
COPY . /app
-
ADD:类似于 COPY,但功能更强大。它可以自动解压归档文件并从 URL 下载文件。例如:
ADD https://example.com/file.tar.gz /app/
-
WORKDIR:设置工作目录。相当于在运行
cd
命令。例如:WORKDIR /app
-
CMD:指定容器启动时要执行的命令。可以被
docker run
命令行参数覆盖。例如:CMD ["nginx", "-g", "daemon off;"]
-
ENTRYPOINT:类似于 CMD,但不可被覆盖,除非使用
--entrypoint
标志。例如:ENTRYPOINT ["nginx", "-g", "daemon off;"]
-
EXPOSE:声明容器监听的端口。例如:
EXPOSE 80
-
ENV:设置环境变量。例如:
ENV LANG C.UTF-8
-
VOLUME:创建挂载点以共享数据。例如:
VOLUME ["/data"]
-
USER:设置运行镜像时的用户名或 UID。例如:
USER nginx
简单示例
以下是一个简单的 Dockerfile 示例,展示了如何创建一个运行 Nginx 的 Docker 镜像:
# 1. 使用官方的 Ubuntu 20.04 作为基础镜像
FROM ubuntu:20.04
# 2. 更新软件包列表并安装 Nginx
RUN apt-get update && apt-get install -y nginx
# 3. 复制本地文件到镜像内
COPY . /usr/share/nginx/html
# 4. 声明容器的监听端口
EXPOSE 80
# 5. 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]
示例中的 Dockerfile 会做以下几件事:
- 使用官方的 Ubuntu 20.04 作为基础镜像。
- 更新软件包列表并安装 Nginx。
- 复制当前目录下的所有文件到镜像的
/usr/share/nginx/html
目录。 - 声明容器将监听 80 端口。
- 启动 Nginx。
通过运行 docker build -t my-nginx .
,可以构建这个镜像。然后使用 docker run -p 80:80 my-nginx
来运行容器,并通过访问主机的 80 端口来查看 Nginx 服务。
实战
近期通过magicapi编写了业务的接口,但由于没有专门进行维护项目的人员,为了方便,通过docker的方式进行部署,但此种部署方式部署直接自己做个镜像,假设容器出了问题,直接删除即可。
在镜像中配置openVPN,为业务访问打通隧道。
环境介绍
系统及版本:Ubuntu 24 64位
Docker版本:26.1.4, build 5650f9b
账户拥有sudo权限或拥有root账户
实现过程
首先创建一个目录。
alex@ubuntu-24:~$ mkdir -p project/docker
进入到目录中,在目录中创建Dockerfile文件
cd project/docker
touch Dockerfile
编写内容如下:
# 使用Centos7作为基础镜像
FROM centos:7
# 安装所需软件包和 JDK 1.8
# 首先安装 EPEL (Extra Packages for Enterprise Linux) 仓库,
# 然后安装 OpenVPN 和 Java 1.8,最后清理 YUM 缓存以减少镜像大小
RUN yum install -y \
epel-release \
&& yum install -y \
openvpn \
java-1.8.0-openjdk-devel \
&& yum clean all
# 设置工作目录
WORKDIR /app
# 复制必要的文件
COPY openvpn.conf /etc/openvpn/
COPY credentials.txt /etc/openvpn/
COPY Magic_API.jar .
# 设置时区为 Asia/Shanghai (UTC+8)
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
# 确定正确的 JAVA_HOME 路径
# 使用 readlink 找到 Java 可执行文件的实际路径,并使用 sed 去除 bin/java 部分,保留 Java 安装目录
RUN export JAVA_HOME=$(readlink -f /usr/bin/java | sed "s:bin/java::")
# 设置环境变量
ENV JAVA_HOME=$JAVA_HOME
ENV PATH=$JAVA_HOME/bin:$PATH
# 暴露端口
EXPOSE 8899
# 将 entrypoint.sh 脚本复制到工作目录,并赋予其可执行权限
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh
# 设置容器启动时执行的命令为启动脚本
ENTRYPOINT ["/app/entrypoint.sh"]
Dockerfile中的四个文件都是需要额外提供。
文件名称 | 作用 |
---|---|
entrypoint.sh | 用于容器启动时的初始化脚本 |
Magic_API.jar | 接口的jar包 |
openvpn.conf | openvpn连接的配置文件 |
credentials.txt | openvpn连接时所用的账号和密码 |
entrypoint.sh脚本内容如下
#!/bin/bash
# 启动 OpenVPN
openvpn --config /etc/openvpn/openvpn.conf --auth-user-pass /etc/openvpn/credentials.txt &
# 启动 Java 应用
exec "$JAVA_HOME/bin/java" -jar /app/Magic_API.jar
openvpn.conf配置文件内容如下:
client
dev-type tun
dev tunx
proto udp
tun-mtu 1500
cipher AES-256-CFB8
comp-lzo
remote ****.alexromeo.net 11194
resolv-retry infinite
nobind
persist-key
persist-tun
verb 3
auth-user-pass
script-security 2
# redirect-gateway
<ca>
-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgIJAMRM7YaxIp26MA0GCSqGSIb3DQEBCwUAMDcxCzAJBgNV
BAYTAkNOMQ4wDAYDVQQKDAVpS3VhaTEYMBYGA1UEAwwPaUt1YWkgRGV2aWNlIENB
MB4XDTIyMDIyMzA2MDU0NFoXDTMyMDIyMTA2MDU0NFowNzELMAkGA1UEBhMCQ04x
...证书文件内容...
33155h63Y1qYjRS8fJwJF6j9kepwxTlMWsBl4EhuJcWeg0y4PqJ7BFp79gxom74S
L4Dp1/mdemwu7wuj9s7dHwiPO4FlH1ox2hDBByWQgbf0GEM5zAeOr0yzFUB0+a/g
34ZIu5M7u39wbqgqYDsL3CwAPiV5
-----END CERTIFICATE-----
</ca>
credentials.txt密码文件内容如下
账号
密码
admin
admin
开始编译
sudo docker build -t magicapi:1.0 .
命令解析:
命令 | 解析 |
---|---|
docker build | Docker CLI 命令,用于从指定的 Dockerfile 构建一个镜像。 |
-t magicapi:1.0 | 为构建的镜像指定名称和标签。-t是--tag的缩写,用于为镜像指定标签;my_custom_image是镜像名称;1.0是镜像的标签。用于区分同一个镜像的不同版本。 |
. | 代表当前目录,即 Dockerfile 所在的目录 |
编译完成的镜像,通过docker image ls可以进行查看。
sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
magicapi 1.0 9003f37c4377 1 hours ago 545MB
创建并启动容器
sudo docker run \
-d \
-p 8899:8899 \
--privileged \
--name ma magicapi
后续通过端口访问服务即可。