从零开始:如何创建和启动 Docker 容器
最近我做了一个 哔哩哔哩直播弹幕姬 项目,为了让大家能更方便地使用,我决定将这个项目容器化,直接用 Docker 一键启动。这样,别人就不用担心配置环境了,直接运行就好。
如果你对 Docker 还不太熟悉,它其实就是一个让你把应用和所有的依赖打包在一起的工具,确保在任何机器上都能以相同的方式运行。通过 Docker,我能把项目打包成容器,避免了不同环境配置不一致的问题。
接下来,我会一步步带你走过:
- 如何写 Dockerfile 来创建镜像;
- 用 docker-compose.yml 来管理多个容器;
- 怎么构建并启动 Docker 容器;
- 容器里的应用怎么配置和运行;
- 如果需要扩展容器环境,应该怎么做。
不管你是刚接触 Docker 还是已经有点经验,相信这篇教程能帮你更好地理解 Docker,并能把自己的项目轻松容器化。
创建 Dockerfile
Dockerfile 是一个文本文件,包含了一系列的指令,Docker 使用这些指令来构建镜像。你可以通过它指定操作系统、安装依赖、复制文件、设置环境变量等。
示例 Dockerfile
1 | FROM php:8.2-cli-alpine |
说明:
FROM:指定基础镜像。
RUN:安装依赖和 PHP 扩展。
COPY:将本地文件复制到容器中。
WORKDIR:设置工作目录。
CMD:容器启动时执行的命令。
创建 Docker Compose 文件
docker-compose.yml 文件定义了多个容器的服务、网络和卷。它让我们可以一键启动多个容器,而不需要手动启动每个容器。
示例 docker-compose.yml
1 | services: |
在上述文件中,定义了三个服务:php、nginx 和 redis,并配置了它们如何协同工作:
PHP 服务:运行应用代码并启动 PHP 和 cron 服务。
Nginx 服务:提供 Web 访问,使用自定义配置文件。
Redis 服务:提供缓存支持。
所有这些服务都连接到同一个自定义网络 webnet,确保它们能够顺畅地通信。
可以通过运行 docker-compose up -d 来启动这些服务,并在浏览器中访问 Nginx 提供的 Web 服务。
PHP 服务
1 | php: |
- build: .:这行代码表示 Docker 会在当前目录下查找 Dockerfile 并基于它构建 PHP 镜像。这个镜像包含了运行 PHP 应用所需的所有依赖和配置。
- container_name: php:为这个容器指定一个名字,便于我们在 Docker 中识别和管理。
- command: sh -c “sh setup.sh && php start.php start -d && crond && tail -f /dev/null”:这行命令会在容器启动时执行。首先,它会运行 setup.sh 脚本,接着启动 PHP 应用(start.php start -d),然后启动 cron 服务(crond),最后使用 tail -f /dev/null 保持容器处于运行状态,防止容器因任务执行完毕而停止。
- volumes:
1 | volumes: |
这行代码将宿主机的 /var/www/bilibili_danmu 目录挂载到容器内部的 /var/www/bilibili_danmu 目录。这确保了 PHP 容器能够访问和处理项目代码。
- networks:
1 | networks: |
容器会连接到一个名为 webnet 的网络,这个网络在文件底部定义。
- expose:
1 | expose: |
expose 命令暴露容器的 7776 端口,供其他容器(如 Nginx)访问。需要注意的是,expose 并不会将端口映射到宿主机,只是让其他容器可以通过这个端口访问。
Nginx 服务
1 | nginx: |
image: nginx:latest:
使用官方的 Nginx 镜像,并始终拉取最新版本。container_name: nginx:
为 Nginx 容器指定一个名字,便于识别。
- volumes:
1 | volumes: |
这两个挂载使得宿主机的 ./nginx/default.conf 配置文件和整个项目目录能够映射到容器内。这样,Nginx 容器就能使用项目的代码和自定义的配置文件。
- ports:
1 | ports: |
这行代码将容器的 80 端口映射到宿主机的 7777 端口,允许外部访问 Nginx 服务。
- networks:
1 | networks: |
Nginx 服务也连接到 webnet 网络,以便和其他容器通信。
- depends_on:
1 | depends_on: |
这表示 Nginx 容器在启动时依赖于 php 容器。depends_on 确保 PHP 容器先启动,以便 Nginx 容器能够访问它。
Redis服务
1 | redis: |
image: redis:latest:
使用官方 Redis 镜像,拉取最新版本。
container_name: redis:
为 Redis 容器指定一个名字,便于管理和识别。
ports:
1 | ports: |
将 Redis 的默认端口 6379 暴露到宿主机上,允许外部程序与 Redis 通信。
networks:
1 | networks: |
Redis 容器连接到 webnet 网络,确保它与 PHP 和 Nginx 容器能够通信。
自定义网络定义
1 | networks: |
networks 定义了一个名为 webnet 的网络,所有容器都将连接到这个网络。通过这种方式,容器间可以互相通信,并且不会暴露给外部世界,除非明确映射端口。这里使用了 bridge 网络驱动,这是 Docker 默认的网络类型,适合容器之间的通信。
构建和启动容器
- 构建 Docker 镜像: 在包含 Dockerfile 与 docker-compose.yml 的目录下运行以下命令构建镜像:
1 | docker-compose build |
- 启动 Docker Compose 服务: 在包含 Dockerfile 与 docker-compose.yml 的目录下运行:
1 | docker-compose up -d |
这条命令会构建和启动所有定义的服务。-d 参数表示在后台运行。
- 查看容器状态: 使用以下命令查看运行中的容器:
1 | docker ps |
- 停止容器: 要停止容器,运行以下命令:
1 | docker-compose down |
其他常用命令
- 查看容器日志:
1 | docker logs <container_name_or_id> |
- 进入容器的终端:
1 | docker exec -it <container_name_or_id> sh |
- 删除容器和镜像:
停止并删除所有容器和镜像:
1 | docker-compose down --rmi all |
- 删除不再使用的资源
以下内容均会被删除:
- 所有未被任何容器使用的镜像(dangling images)
- 所有停止的容器(stopped containers)
- 所有未被使用的网络(unused networks)
- 所有未被使用的卷(未使用的匿名卷,需加 –volumes 才会删除)
- 所有未使用的构建缓存
1 | docker system prune |
- 感谢您的赞赏