Docker制作自己的镜像

Docker制作自己的镜像
墨颜丶需求:
- 基于docker创建在python 3.10.13上运行我们开发的Flask网站。
流程:
基于docker软件
在基础镜像基础上构建自定义镜像[ python 3.10.13+代码]
基于镜像创建容器+运行
安装 Docker
首先,确保你已经在你的系统上安装了Docker。你可以访问Docker的官方网站,按照适用于你的操作系统的指南来安装。
编写Dockerfile
在你的Flask项目目录中创建一个名为Dockerfile
的文件,导出pip freeze > requirements.txt
依赖,并添加以下内容:
1 | 使用官方Python 3.10.13镜像作为基础镜像 |
当你使用官方的Python镜像作为基础镜像时,你就不需要再指定一个基础的系统镜像了,因为Python镜像本身就是基于一个特定的操作系统镜像(比如Debian、Ubuntu或其他)构建的,并且已经包含了特定版本的Python解释器和其他常用的工具。
在这个简化的Dockerfile中,我们直接使用了官方的Python 3.10.13镜像作为基础,然后设置了工作目录,拷贝了应用文件,并安装了Flask。这样可以确保我们使用的是特定版本的Python,而无需担心如何在基础操作系统上安装它。
使用官方Python镜像的好处是它们经过了官方的维护和测试,确保了Python环境的稳定性和一致性。此外,这些镜像通常也比较小,因为它们针对Python环境进行了优化,不包含不必要的系统和软件包。这样可以使你的Docker镜像更小、更快构建,并且更容易维护。
构建镜像
在包含Dockerfile
和app.py
的目录中执行以下命令来构建自定义镜像:
1 | docker build -t jerry/web1:1.0 . |
这里的-t
参数用于指定镜像的名称和标签。jerry/flask-app
是镜像的名称,v1.0
是标签,用于标识镜像的版本。.
表示Dockerfile所在的当前目录。
注意:
- 不需要指定
-f Dockerfile
,因为Docker默认会查找当前目录下的Dockerfile
。
1 | docker build -t jerry/web1:1.0 . -f Dockerfil |
这里是一个简化的过程:
- 你编写一个包含
FROM python:3.10.13
的 Dockerfile。 - 你运行
docker build -t your-image-name .
(注意最后的点.
表示 Dockerfile 所在的上下文路径)。 - Docker 开始构建你的镜像。
- Docker 检查本地是否有
python:3.10.13
这个基础镜像。 - 如果本地没有这个镜像,Docker 会自动从 Docker Hub 拉取
python:3.10.13
。 - 一旦基础镜像拉取完成,Docker 会继续按照 Dockerfile 中的指令构建你的镜像。
基于镜像创建容器+运行
使用以下命令来创建并运行容器:
1 | 创建并运行第一个容器,映射宿主机的80端口到容器的8000端口 |
这样,我们就创建了三个基于同一个镜像的容器,每个容器都运行着我们的Flask应用,并通过不同的端口对外提供服务。
这里的参数解释如下:
-d
:在后台运行容器。-p 80:5000
:将宿主机的80端口映射到容器的5000端口。这样,你就可以通过访问宿主机的80端口来访问你的Flask应用了。--name my-flask-container
:给容器指定一个名称,方便后续管理。jerry/flask-app:v1.0
:要运行的镜像名称和标签。
访问你的Flask应用
现在,你的Flask应用应该已经在Docker容器中运行了。你可以通过访问宿主机的IP地址和映射的端口(在这个例子中是http://<host_ip>:80
)来查看你的Flask网站。
注意事项和拓展
- 确保你的Flask应用的入口文件是
app.py
,并且它配置为在5000端口上运行。如果不是这样,你需要在Dockerfile中相应地调整CMD
指令。 - 如果你的Flask应用需要数据库或其他服务,你可以在Dockerfile中添加相应的安装和配置步骤,或者使用Docker Compose来管理多个容器和服务。
- 你可以根据需要添加更多的环境变量、配置或优化步骤到Dockerfile中,以满足你的特定需求。
- 使用Docker可以方便地扩展你的Flask应用。你可以通过运行多个容器实例来提高应用的可用性和性能。每个容器实例都是独立的,并且可以轻松地进行扩展或缩减。
- 容器中必须有前台进程,否则创建立即销毁。
Docker 容器在启动时需要一个前台进程来保持容器的运行状态。当容器内没有前台进程时,它会立即退出。这是因为 Docker 容器是基于进程的,它不会管理后台服务或守护进程。
关于你提到的 systemctl
命令,通常它用于管理系统的服务,而在 Docker 容器中并不适用,因为容器通常没有完整的系统服务管理能力。相反,你应该直接运行你的应用程序或服务的可执行文件,并确保它以前台模式运行。
对于 Nginx:
1 | 比如 |
这将使 Nginx 以非守护进程模式运行,作为前台进程保持容器的运行状态。
docker run
的正确用法docker run
命令用于从指定的镜像创建并启动一个新的容器。它通常用于部署应用程序或服务。正确的用法包括指定镜像名称或ID,以及任何必要的运行参数和命令。例如:
docker run -ti --rm <image_name> bash
这个命令会做以下事情:
-t
:分配一个伪终端(pseudo-TTY),以便可以交互式地运行容器。-i
:保持容器的标准输入(STDIN)打开,这样你可以与容器进行交互。--rm
:在容器退出后自动删除容器。image_name
:这是你要基于的镜像名称。bash
:这是在容器内部要运行的命令。在这个例子中,我们启动一个 bash shell。
这个命令用于从指定的 Docker 镜像启动一个新的容器实例,并在容器内部运行一个命令。
docker exec
的正确用法
docker exec
命令用于在正在运行的容器内部执行一个命令。它允许你与正在运行的容器进行交互,例如运行额外的命令或脚本。
首先,你需要知道正在运行的容器的 ID 或名称。你可以使用 docker ps
命令来获取这个信息。
然后,你可以使用 docker exec
在该容器内执行命令。例如:
docker exec -ti <container_id_or_name> bash
这个命令用于在已经运行的 Docker 容器中执行一个命令。具体来说,docker exec
命令允许你在一个正在运行的容器内部启动一个额外的进程。
-t
或--tty
:同样用于分配一个伪终端。-i
或--interactive
:保持 STDIN 开放。docker exec
是用来在已经运行的容器中执行命令的。docker run
是用来从指定的镜像创建并启动新的容器实例的。
1 | 进入正在运行的容器的bash环境 |
- 如果是Django呢?
1 | RUN pip install --no-cache-dir -r requirements.txt |
切换目录
在 Dockerfile 中,您可以多次使用
WORKDIR
指令来更改当前工作目录。每次使用WORKDIR
时,它都会将后续的指令(如RUN
、COPY
等)设置在那个指定的目录下执行。
1 | 进入/data目录 |
每个 WORKDIR
指令都会更改当前工作目录,而紧接着的 RUN
指令(或其他需要路径的指令)会在那个新的工作目录下执行。这种方式使得 Dockerfile 更加模块化和清晰,因为您可以明确知道每个指令在哪个目录下执行。
请注意,如果指定的目录不存在,WORKDIR
会自动创建该目录。所以,在例子中,如果 /data
或 /tmp
目录在镜像中不存在,它们将被自动创建。
文笔流畅美,点赞纷至来;
内容引入胜,分享乐开怀;
佳作值得赏,打赏表心怀。