星河避难所

返回

从零开始:如何创建和启动 Docker 容器Blur image

最近我做了一个 哔哩哔哩直播弹幕姬 项目,为了让大家能更方便地使用,我决定将这个项目容器化,直接用 Docker 一键启动。这样,别人就不用担心配置环境了,直接运行就好。

如果你对 Docker 还不太熟悉,它其实就是一个让你把应用和所有的依赖打包在一起的工具,确保在任何机器上都能以相同的方式运行。通过 Docker,我能把项目打包成容器,避免了不同环境配置不一致的问题。

接下来,我会一步步带你走过:

  1. 如何写 Dockerfile 来创建镜像;
  2. 用 docker-compose.yml 来管理多个容器;
  3. 怎么构建并启动 Docker 容器;
  4. 容器里的应用怎么配置和运行;
  5. 如果需要扩展容器环境,应该怎么做。

不管你是刚接触 Docker 还是已经有点经验,相信这篇教程能帮你更好地理解 Docker,并能把自己的项目轻松容器化。

创建 Dockerfile#

Dockerfile 是一个文本文件,包含了一系列的指令,Docker 使用这些指令来构建镜像。你可以通过它指定操作系统、安装依赖、复制文件、设置环境变量等。

示例 Dockerfile

FROM php:8.2-cli-alpine

# 安装 Composer
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer

# 设置环境变量
ENV TZ=Asia/Shanghai

# 更新软件包列表并安装系统依赖
RUN apk update && apk add --no-cache \
    bash \
    git \
    curl \
    brotli \
    build-base \
    autoconf \
    libtool \
    make \
    linux-headers \
    pcre-dev \
    libevent \
    libevent-dev \
    libpng-dev \
    libjpeg-turbo-dev \
    libwebp-dev \
    freetype-dev \
    $PHPIZE_DEPS \
    redis \
    busybox-suid  # 添加 cron 支持

# 安装 PHP 扩展
RUN docker-php-ext-install pdo_mysql pcntl

# 安装 PHP GD 扩展
RUN docker-php-ext-configure gd \
    --with-jpeg \
    --with-webp \
    --with-freetype \
    && docker-php-ext-install gd

# 安装 PHP Redis 扩展
RUN pecl install redis \
    && docker-php-ext-enable redis

# 安装 PHP Brotli 扩展
RUN pecl install brotli \
    && docker-php-ext-enable brotli

# 设置工作目录
WORKDIR /var/www/bilibili_danmu

# 复制项目文件到容器中
RUN git clone https://github.com/zxc7563598/php-bilibili-danmu.git /var/www/bilibili_danmu

# 安装 PHP 依赖(生产环境中使用 --no-dev)
RUN composer install

# 设置目录权限
RUN chmod +x /var/www/bilibili_danmu

# 添加 cron 任务
RUN echo "0 * * * * /var/www/bilibili_danmu/check_and_update.sh" > /etc/crontabs/root
dockerfile

说明: FROM:指定基础镜像。 RUN:安装依赖和 PHP 扩展。 COPY:将本地文件复制到容器中。 WORKDIR:设置工作目录。 CMD:容器启动时执行的命令。

创建 Docker Compose 文件#

docker-compose.yml 文件定义了多个容器的服务、网络和卷。它让我们可以一键启动多个容器,而不需要手动启动每个容器。

示例 docker-compose.yml

services:
  php:
    build: .
    container_name: php
    command: sh -c "sh setup.sh && php start.php start -d && crond && tail -f /dev/null"
    volumes:
      - /var/www/bilibili_danmu
    networks:
      - webnet
    expose:
      - '7776'

  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - .:/var/www/bilibili_danmu
    ports:
      - '7777:80'
    networks:
      - webnet
    depends_on:
      - php

  redis:
    image: redis:latest
    container_name: redis
    ports:
      - '6379'
    networks:
      - webnet

networks:
  webnet:
    driver: bridge
yml

在上述文件中,定义了三个服务:php、nginx 和 redis,并配置了它们如何协同工作:

PHP 服务:运行应用代码并启动 PHP 和 cron 服务。

Nginx 服务:提供 Web 访问,使用自定义配置文件。

Redis 服务:提供缓存支持。

所有这些服务都连接到同一个自定义网络 webnet,确保它们能够顺畅地通信。

可以通过运行 docker-compose up -d 来启动这些服务,并在浏览器中访问 Nginx 提供的 Web 服务。

PHP 服务#

php:
  build: .
  container_name: php
  command: sh -c "sh setup.sh && php start.php start -d && crond && tail -f /dev/null"
  volumes:
    - /var/www/bilibili_danmu
  networks:
    - webnet
  expose:
    - '7776'
yml
  • 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
volumes:
  - /var/www/bilibili_danmu
yml

这行代码将宿主机的 /var/www/bilibili_danmu 目录挂载到容器内部的 /var/www/bilibili_danmu 目录。这确保了 PHP 容器能够访问和处理项目代码。

  • networks
networks:
  - webnet
yml

容器会连接到一个名为 webnet 的网络,这个网络在文件底部定义。

  • expose
expose:
  - '7776'
yml

expose 命令暴露容器的 7776 端口,供其他容器(如 Nginx)访问。需要注意的是,expose 并不会将端口映射到宿主机,只是让其他容器可以通过这个端口访问。

Nginx 服务#

nginx:
  image: nginx:latest
  container_name: nginx
  volumes:
    - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    - .:/var/www/bilibili_danmu
  ports:
    - '7777:80'
  networks:
    - webnet
  depends_on:
    - php
yml
  • image: nginx:latest: 使用官方的 Nginx 镜像,并始终拉取最新版本。

  • container_name: nginx

为 Nginx 容器指定一个名字,便于识别。

  • volumes
volumes:
  - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
  - .:/var/www/bilibili_danmu
yml

这两个挂载使得宿主机的 ./nginx/default.conf 配置文件和整个项目目录能够映射到容器内。这样,Nginx 容器就能使用项目的代码和自定义的配置文件。

  • ports
ports:
  - '7777:80'
yml

这行代码将容器的 80 端口映射到宿主机的 7777 端口,允许外部访问 Nginx 服务。

  • networks
networks:
  - webnet
yml

Nginx 服务也连接到 webnet 网络,以便和其他容器通信。

  • depends_on
depends_on:
  - php
yml

这表示 Nginx 容器在启动时依赖于 php 容器。depends_on 确保 PHP 容器先启动,以便 Nginx 容器能够访问它。

Redis 服务#

redis:
  image: redis:latest
  container_name: redis
  ports:
    - '6379'
  networks:
    - webnet
yml

image: redis:latest: 使用官方 Redis 镜像,拉取最新版本。

container_name: redis: 为 Redis 容器指定一个名字,便于管理和识别。

ports

ports:
  - '6379'
yml

将 Redis 的默认端口 6379 暴露到宿主机上,允许外部程序与 Redis 通信。

networks

networks:
  - webnet
yml

Redis 容器连接到 webnet 网络,确保它与 PHP 和 Nginx 容器能够通信。

自定义网络定义#

networks:
  webnet:
    driver: bridge
yml

networks 定义了一个名为 webnet 的网络,所有容器都将连接到这个网络。通过这种方式,容器间可以互相通信,并且不会暴露给外部世界,除非明确映射端口。这里使用了 bridge 网络驱动,这是 Docker 默认的网络类型,适合容器之间的通信。

构建和启动容器#

  • 构建 Docker 镜像: 在包含 Dockerfiledocker-compose.yml 的目录下运行以下命令构建镜像:
docker-compose build
shell
  • 启动 Docker Compose 服务: 在包含 Dockerfiledocker-compose.yml 的目录下运行:
docker-compose up -d
shell

这条命令会构建和启动所有定义的服务。-d 参数表示在后台运行。

  • 查看容器状态: 使用以下命令查看运行中的容器:
docker ps
shell
  • 停止容器: 要停止容器,运行以下命令:
docker-compose down
shell

其他常用命令#

  • 查看容器日志
docker logs <container_name_or_id>
bash
  • 进入容器的终端
docker exec -it <container_name_or_id> sh
bash
  • 删除容器和镜像: 停止并删除所有容器和镜像:
docker-compose down --rmi all
bash
  • 删除不再使用的资源

以下内容均会被删除:

  1. 所有未被任何容器使用的镜像(dangling images)
  2. 所有停止的容器(stopped containers)
  3. 所有未被使用的网络(unused networks)
  4. 所有未被使用的卷(未使用的匿名卷,需加 —volumes 才会删除)
  5. 所有未使用的构建缓存
docker system prune
bash
从零开始:如何创建和启动 Docker 容器
https://hejunjie.life/blog/26ee1ee8
作者 何俊杰
发布时间 2024年12月1日
版权信息 CC BY-NC-SA 4.0
评论似乎卡住了,尝试刷新?✨