去年还在手动装 Nginx、PHP、MySQL 配环境,今年用 Docker 一行命令就把整个项目跑起来了。这篇记录一下从零到部署的全过程。
Docker 到底是个啥
别被那些高大上的术语忽悠了。
Docker 本质上就是个打包工具——把你的应用和它需要的所有东西(系统库、运行环境、配置文件)打包成一个「箱子」,这个箱子在任何装了 Docker 的机器上都能跑。
不用 Docker 的痛
- 「在我电脑上跑得好好的」——换台服务器就报错了
- 版本冲突:项目 A 要 PHP 7.4,项目 B 要 PHP 8.3
- 换服务器要重新装一遍环境
- 团队协作,每个人的开发环境不一样
用 Docker 之后
- 环境一致:开发、测试、生产完全一样
- 快速部署:一条命令启动整个服务栈
- 隔离:每个应用在自己的容器里,互不影响
- 迁移方便:把镜像拷走就行
核心概念(用大白话说)
| 概念 | 大白话解释 | 类比 |
|---|---|---|
| 镜像(Image) | 打包好的应用模板 | 安装光盘 / ISO 文件 |
| 容器(Container) | 镜像跑起来的实例 | 用光盘装好的系统 |
| Dockerfile | 告诉 Docker 怎么打包的清单 | 菜谱 |
| Docker Compose | 管理多个容器的工具 | 管家 |
| 仓库(Registry) | 存放镜像的地方 | 应用商店 |
| Docker Hub | 官方镜像仓库 | App Store |
安装 Docker
Ubuntu / Debian
# 一行脚本搞定
curl -fsSL https://get.docker.com | bash
# 验证安装
docker --version
# 输出类似:Docker version 28.0.4, build b8e86a2Windows / macOS
直接装 Docker Desktop:
- Windows: docker.com/products/docker-desktop
- macOS: 同上
Docker Desktop 自带图形界面,对新手友好。
国内加速
Docker Hub 国内访问慢,建议配置镜像加速器:
# 编辑 /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}
# 重启 Docker
systemctl restart docker2024-2025 年国内 Docker Hub 镜像加速服务变化比较大,之前常用的几个(阿里云、中科大)有些不稳定了。上面列出的是 2026 年初还在正常运行的。如果打不开可以搜 "Docker Hub 国内镜像" 找最新的。
第一个 Docker 命令
跑个 Nginx 试试
docker run -d -p 8080:80 --name mysite nginx然后浏览器打开 http://你的IP:8080,就能看到 Nginx 的欢迎页面了。
这一条命令做了什么事:
- 从 Docker Hub 拉取
nginx镜像 - 创建一个容器,名字叫
mysite - 把容器的 80 端口映射到宿主机的 8080 端口
- 后台运行(
-d)
常用命令速查
| 命令 | 作用 |
|---|---|
docker ps | 查看正在运行的容器 |
docker ps -a | 查看所有容器(包括停止的) |
docker images | 查看本地镜像 |
docker stop 容器名 | 停止容器 |
docker start 容器名 | 启动容器 |
docker rm 容器名 | 删除容器 |
docker rmi 镜像名 | 删除镜像 |
docker logs 容器名 | 查看容器日志 |
docker exec -it 容器名 bash | 进入容器内部 |
Docker Compose:多个容器一起管
实际建站不会只跑一个服务。至少得有个 Nginx + PHP + MySQL 的组合。
一个个 docker run 太麻烦,Docker Compose 让你用一个文件定义所有服务。
用 Compose 部署 WordPress
新建一个 docker-compose.yml:
version: '3.8'
services:
# MySQL 数据库
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: your-root-password
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wp-password
volumes:
- db_data:/var/lib/mysql
# WordPress
wordpress:
image: wordpress:6.7-php8.3-apache
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wp-password
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
depends_on:
- db
# phpMyAdmin(数据库管理)
phpmyadmin:
image: phpmyadmin:latest
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: your-root-password
depends_on:
- db
volumes:
db_data:
wp_data:然后一条命令启动全部服务:
docker compose up -d这就跑起来了。Nginx/Apache、PHP、MySQL、phpMyAdmin,全在各自的容器里。
查看和管理
# 看看所有容器状态
docker compose ps
# 查看 WordPress 日志
docker compose logs -f wordpress
# 停止所有服务
docker compose down
# 更新镜像并重新部署
docker compose pull
docker compose up -d实战:用 Docker 部署你自己的项目
假设你有一个 PHP 项目,目录结构:
my-project/
├── src/
│ └── index.php
├── public/
└── docker-compose.yml第一步:写 Dockerfile
在项目根目录创建 Dockerfile(没有扩展名):
# 基于官方 PHP 8.3 FPM 镜像
FROM php:8.3-fpm
# 安装常用扩展
RUN docker-php-ext-install pdo_mysql mysqli mbstring
# 安装 Composer
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
# 设置工作目录
WORKDIR /var/www/html
# 复制项目文件
COPY . .
# 安装依赖
RUN composer install --no-dev --optimize-autoloader
# 设置权限
RUN chown -R www-data:www-data /var/www/html第二步:写 docker-compose.yml
version: '3.8'
services:
app:
build: . # 从当前目录的 Dockerfile 构建
restart: always
volumes:
- ./src:/var/www/html # 代码目录挂载(开发时不用重建)
networks:
- appnet
nginx:
image: nginx:1.27
restart: always
ports:
- "80:80"
volumes:
- ./src:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- appnet
db:
image: mariadb:11.4 # MariaDB 是 MySQL 的开源替代
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: mydb
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
volumes:
- db_data:/var/lib/mysql
networks:
- appnet
networks:
appnet:
driver: bridge
volumes:
db_data:第三步:Nginx 配置
nginx.conf:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass app:9000; # 注意这里用服务名 "app" 而不是 localhost
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}第四步:启动
docker compose up -d打开 http://你的IP,应该就能看到你的项目了。
Docker 常用场景
| 场景 | 推荐方案 |
|---|---|
| 个人博客 | wordpress:latest 或 ghost:latest |
| PHP 项目 | 自定义 Dockerfile + nginx + mariadb |
| Node.js 项目 | node:20 基础镜像 |
| Python 项目 | python:3.12 基础镜像 |
| 数据库管理 | phpmyadmin 或 adminer |
| 缓存 | redis:7-alpine |
| 反向代理 | traefik 或 nginx-proxy |
| 全部一起 | Docker Compose |
一些踩坑经验
1. 数据别存 Volume 里,别存容器里
容器删了重建,里面的数据就没了。数据库文件、上传的图片这些要持久化的数据,一定要用 volumes 或 bind mount 映射出来。
2. 开发环境和生产环境分开
开发时可以挂载本地代码目录(./src:/var/www/html),改了代码实时生效。生产环境直接把代码 COPY 进镜像,更稳定。
3. 镜像不要太大
用 -alpine 版本的基础镜像(比如 php:8.3-fpm-alpine),体积只有完整版的 1/5。
4. 端口冲突
如果 8080 端口已经被占用了,docker compose up 会报错。换一个没被占用的端口就行。
2026 年 Docker 生态速览
| 工具/服务 | 说明 | 2026 状态 |
|---|---|---|
| Docker Desktop | 官方桌面管理工具 | 免费 + 付费版 |
| Portainer | 开源 Docker 管理面板 | 活跃维护中 |
| Docker Compose V2 | 集成到 Docker CLI 中 | 已成标准 |
| Podman | Docker 的无守护进程替代 | 增长中,RedHat 主推 |
| OrbStack | macOS 上 Docker Desktop 的轻量替代 | 快速崛起 |
常见问题
Docker 和虚拟机有什么区别?
虚拟机模拟整个操作系统(每个 VM 有独立的内核),Docker 共享宿主机内核。所以 Docker 启动只要几秒,内存占用也更少。
我的服务器只有 1G 内存,能跑 Docker 吗?
能,但比较紧张。Docker 守护进程本身占 100-200MB,加上跑的服务,1G 内存跑 2-3 个轻量容器没问题。建议用 -alpine 镜像节省空间。
Docker 安全吗?
默认配置下,容器之间是隔离的。但容器以 root 运行,如果配置不当可能有安全隐患。生产环境建议用非 root 用户跑容器。
叙云博客后续会有更多 Docker 实战内容,比如用 Traefik 做反向代理、自动 HTTPS、容器编排等。

暂无评论内容