学习 docker 也快一个来月了,断断续续,又是百度,又是AI的,终于掌握了他的一些基础理论和原理。

docker是什么

docker 用直白点的话来说,就是将所有的服务、应用、以及代码依赖打包成一个镜像。使用的人只要通过 docker 的命令 执行这个镜像就可以完整把项目考贝到自己的电脑上。省去了开发人员在构建项目时版本或依赖库不统一的烦恼。

docker安装和使用

docker安装

# 下载并执行Docker官方安装脚本
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker

docker使用

docker 其实包括两个主要文件,dockerfile 和 docker-compose,前者是做为镜像存在,后者是根打包应用所需要执行的操作。我先来一个例子来讲解。

dockerfile

在docker的官方 nginx镜像中,只有基础的功能。并没有反向代理。假如说我们需要拿到某个镜像之后就有反向代理的功能。那么,我们就可以使用dockerfile来实现。

#Dockerfile 文件
FROM nginx:alpine

# 复制自定义的nginx配置文件到容器中
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 暴露80端口
EXPOSE 80

# 启动nginx服务
CMD ["nginx", "-g", "daemon off;"]

#default.conf 文件
server {
    listen 80;
    server_name localhost;

    # 将所有/goods开头的请求代理到goodsUrl
    location /goods {
        # 替换为实际的goods服务URL
        proxy_pass http://goodsUrl;
        
        # 反向代理的常用配置
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 其他请求的处理(可选)
    location / {
        # 可以配置默认页面或其他服务
        root /usr/share/nginx/html;
        index index.html index.htm;
    }
}

#执行的命令
#!/bin/bash

# 构建镜像
docker build -t nginx-proxy .

# 运行容器,将本地80端口映射到容器的80端口
docker run -d -p 80:80 --name goods-proxy nginx-proxy

也就是说,这个构建出来的镜像就是反向代理。当访问 goods的时候,就会路邮到 goodsUrl的路径下。

docker-compose

假如说项目需要有多个服务,那么这个时候 docker-compose 就是为这个量身定做的。说白了,docker-compose 是将多个服务务打包在一起运行,谁先执行,哪个服务依赖于哪个服务。就是干这个用的。我以用ai生成的 cocker-compose来讲解,注释ai也帮我写好了。注意,docker-compose它的扩展名是yaml。

version: '3.8'  # 兼容大多数 Docker 版本

# 定义所有服务(容器)
services:
  # 1. MySQL 服务(数据库)
  mysql:
    image: mysql:8.0  # 使用官方 MySQL 镜像(无需自己构建)
    container_name: laravel-mysql  # 容器名称(方便识别)
    restart: always  # 容器崩溃时自动重启
    environment:  # 环境变量(数据库配置)
      MYSQL_ROOT_PASSWORD: root123456  # 根用户密码
      MYSQL_DATABASE: laravel_db       # 为 Laravel 创建的数据库名
      MYSQL_USER: laravel_user         # 数据库用户(给 Laravel 用)
      MYSQL_PASSWORD: laravel_pwd123   # 用户密码
    volumes:
      # 数据持久化:将 MySQL 数据目录挂载到本地(容器删除数据不丢失)
      - mysql_data:/var/lib/mysql
    networks:
      - laravel-network  # 加入自定义网络,与其他服务通信

  # 2. Redis 服务(缓存/会话/队列)
  redis:
    image: redis:alpine  # 轻量版 Redis 镜像
    container_name: laravel-redis
    restart: always
    volumes:
      - redis_data:/data  # 持久化 Redis 数据
    networks:
      - laravel-network

  # 3. PHP 服务(运行 Laravel 代码)
  php:
    build: ./php  # 关键:基于 ./php 目录的 Dockerfile 构建自定义 PHP 镜像
    container_name: laravel-php
    restart: always
    depends_on:
      - mysql  # 依赖 MySQL:启动时先启动 MySQL
      - redis  # 依赖 Redis:启动时先启动 Redis
    volumes:
      # 挂载 Laravel 代码:本地 src 目录 → 容器内 /var/www/laravel
      - ./src:/var/www/laravel
      # 挂载 PHP 配置:覆盖容器默认的 php.ini
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini
    environment:
      # 传递环境变量(可选,也可在 Laravel 的 .env 中配置)
      - DB_HOST=mysql
      - REDIS_HOST=redis
    networks:
      - laravel-network

  # 4. Nginx 服务(处理 HTTP 请求)
  nginx:
    image: nginx:latest  # 使用官方 Nginx 镜像
    container_name: laravel-nginx
    restart: always
    depends_on:
      - php  # 依赖 PHP:启动时先启动 PHP
    ports:
      # 端口映射:宿主机 80 端口 → 容器 80 端口(外部可访问)
      - "80:80"
    volumes:
      # 挂载 Nginx 配置:覆盖容器默认配置
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      # 共享 Laravel 代码:与 PHP 容器访问同一份代码
      - ./src:/var/www/laravel
    networks:
      - laravel-network

# 定义数据卷(持久化数据,独立于容器生命周期)
volumes:
  mysql_data:  # 存储 MySQL 数据
  redis_data:  # 存储 Redis 数据

# 定义自定义网络(所有服务在同一网络,可通过服务名通信)
networks:
  laravel-network:
    driver: bridge  # 桥接网络(默认类型)

根据b站那儿的讲解,docker-compose 它主要的根节点包括如下

#版本号
version:
#所需要服务
services:
	mysql:
	php:
	redis:
	nginx:
#卷目录
volumes:
#网络
networks:

到这儿,我不知道大家有没有对 docker 有一个大概的了解呢。在最后,我将以 laravel 来部署一个完整的项目。

docker部署laravel项目

目录结构

laravel-docker/
├── docker-compose.yml       # 核心:定义所有服务的关系和规则
├── php/                     # PHP 相关(自定义镜像)
│   ├── Dockerfile           # 构建 PHP 镜像(安装 Laravel 必需的扩展)
│   └── php.ini              # PHP 配置(可选,优化运行参数)
├── nginx/                   # Nginx 相关
│   └── nginx.conf           # Nginx 配置(处理请求转发到 PHP)
└── src/                     # Laravel 代码(需提前准备)
    ├── .env                 # Laravel 环境配置
    └── ...(其他 Laravel 文件)

代码块

PHP 的 Dockerfile(php/Dockerfile)
# 基础镜像:官方 PHP 8.2 带 FPM(适合 Laravel 最新版本)
FROM php:8.2-fpm

# 安装系统依赖(编译 PHP 扩展需要)
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    libzip-dev \
    zip \
    unzip \
    && rm -rf /var/lib/apt/lists/*  # 清理缓存,减小镜像体积

# 安装 Laravel 必需的 PHP 扩展
RUN docker-php-ext-install \
    pdo_mysql \       # 数据库连接(Laravel 核心)
    mbstring \        # 多字节字符串处理
    exif \            # 图片元数据处理
    pcntl \           # 进程控制(队列等功能)
    bcmath \          # 数学运算
    gd \              # 图片处理
    zip               # 压缩文件处理

# 安装 Redis 扩展(Laravel 缓存/队列常用)
RUN pecl install redis && docker-php-ext-enable redis

# 安装 Composer(PHP 包管理工具,用于安装 Laravel 依赖)
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# 设置工作目录(容器内的 Laravel 代码存放路径)
WORKDIR /var/www/laravel

# 修复权限问题(避免 Laravel 写入 storage 目录时出错)
RUN chown -R www-data:www-data /var/www/laravel

PHP 配置(php/php.ini,可选)
max_execution_time = 60
memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M
date.timezone = Asia/Shanghai  # 设置时区为上海

Nginx 配置(nginx/nginx.conf)
server {
    listen 80;
    server_name localhost;  # 本地访问用 localhost

    # Laravel 的入口目录是 public(安全最佳实践)
    root /var/www/laravel/public;
    index index.php index.html;

    # 处理静态资源(直接返回,不经过 PHP)
    location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
        expires 30d;  # 缓存 30 天,提升性能
        add_header Cache-Control "public, max-age=2592000";
    }

    # 转发 PHP 请求到 PHP 容器(关键)
    location ~ \.php$ {
        # "php" 是 docker-compose 中定义的 PHP 服务名,自动解析为容器 IP
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        # 告诉 PHP 脚本的实际路径(容器内的路径)
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;  # 包含默认的 FastCGI 参数
    }

    # Laravel 路由重写(去除 URL 中的 index.php)
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

docker-compose.yml(核心配置)
version: '3.8'  # 兼容大多数 Docker 版本

# 定义所有服务(容器)
services:
  # 1. MySQL 服务(数据库)
  mysql:
    image: mysql:8.0  # 使用官方 MySQL 镜像(无需自己构建)
    container_name: laravel-mysql  # 容器名称(方便识别)
    restart: always  # 容器崩溃时自动重启
    environment:  # 环境变量(数据库配置)
      MYSQL_ROOT_PASSWORD: root123456  # 根用户密码
      MYSQL_DATABASE: laravel_db       # 为 Laravel 创建的数据库名
      MYSQL_USER: laravel_user         # 数据库用户(给 Laravel 用)
      MYSQL_PASSWORD: laravel_pwd123   # 用户密码
    volumes:
      # 数据持久化:将 MySQL 数据目录挂载到本地(容器删除数据不丢失)
      - mysql_data:/var/lib/mysql
    networks:
      - laravel-network  # 加入自定义网络,与其他服务通信

  # 2. Redis 服务(缓存/会话/队列)
  redis:
    image: redis:alpine  # 轻量版 Redis 镜像
    container_name: laravel-redis
    restart: always
    volumes:
      - redis_data:/data  # 持久化 Redis 数据
    networks:
      - laravel-network

  # 3. PHP 服务(运行 Laravel 代码)
  php:
    build: ./php  # 关键:基于 ./php 目录的 Dockerfile 构建自定义 PHP 镜像
    container_name: laravel-php
    restart: always
    depends_on:
      - mysql  # 依赖 MySQL:启动时先启动 MySQL
      - redis  # 依赖 Redis:启动时先启动 Redis
    volumes:
      # 挂载 Laravel 代码:本地 src 目录 → 容器内 /var/www/laravel
      - ./src:/var/www/laravel
      # 挂载 PHP 配置:覆盖容器默认的 php.ini
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini
    environment:
      # 传递环境变量(可选,也可在 Laravel 的 .env 中配置)
      - DB_HOST=mysql
      - REDIS_HOST=redis
    networks:
      - laravel-network

  # 4. Nginx 服务(处理 HTTP 请求)
  nginx:
    image: nginx:latest  # 使用官方 Nginx 镜像
    container_name: laravel-nginx
    restart: always
    depends_on:
      - php  # 依赖 PHP:启动时先启动 PHP
    ports:
      # 端口映射:宿主机 80 端口 → 容器 80 端口(外部可访问)
      - "80:80"
    volumes:
      # 挂载 Nginx 配置:覆盖容器默认配置
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      # 共享 Laravel 代码:与 PHP 容器访问同一份代码
      - ./src:/var/www/laravel
    networks:
      - laravel-network

# 定义数据卷(持久化数据,独立于容器生命周期)
volumes:
  mysql_data:  # 存储 MySQL 数据
  redis_data:  # 存储 Redis 数据

# 定义自定义网络(所有服务在同一网络,可通过服务名通信)
networks:
  laravel-network:
    driver: bridge  # 桥接网络(默认类型)

src/.env 文件

这儿有一个需要注的地方,那就是这个env配置文件的内容,需要跟 docker-compose所提到的要一致。比如说提及到的数据库、redis 等等 。

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=laravel_pwd123

REDIS_HOST=redis
REDIS_PORT=6379
启动服务

在根目录执行如下命令

docker compose up -d --build  # --build 表示构建自定义 PHP 镜像
初始化项目
docker compose exec php bash  # 进入 PHP 容器
composer install              # 安装 Laravel 依赖
php artisan key:generate      # 生成应用密钥
php artisan migrate           # 执行数据库迁移(创建表)

到此,整个配置完成。学习了近一个来月,虽然这些代码都是从ai上而来,但我也理解了它的常用方法。但更多的细节我还得在研究研究。

docker-composer.yaml
services:
  # 反向代理/网关
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./user-service/public:/var/www/html/public
    depends_on:
      - user-service
    networks:
      - laravel-network
    # 🔥 新增DNS配置,解决网络解析慢
    dns:
      - 223.5.5.5    # 阿里云DNS
      - 8.8.8.8      # 谷歌DNS

  # MySQL 数据库
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: user_db
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    volumes:
      - mysql-data:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3306:3306"
    networks:
      - laravel-network
    command: --default-authentication-plugin=mysql_native_password
    # 🔥 新增DNS配置
    dns:
      - 223.5.5.5
      - 8.8.8.8

  # 用户服务
  user-service:
    build:
      context: ./user-service
      dockerfile: Dockerfile
    volumes:
      - ./user-service:/var/www/html
    environment:
      DB_CONNECTION: mysql
      DB_HOST: mysql
      DB_PORT: 3306
      DB_DATABASE: user_db
      DB_USERNAME: laravel
      DB_PASSWORD: secret
      REDIS_HOST: redis
    networks:
      - laravel-network
    depends_on:
      - mysql
    # 🔥 新增DNS配置(核心,解决composer拉取包超时)
    dns:
      - 223.5.5.5
      - 8.8.8.8

networks:
  laravel-network:
    driver: bridge

volumes:
  mysql-data:
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐