一、前言
Docker 是一种容器化技术,它能把应用及其运行环境打包成一个轻量、可移植的镜像。镜像运行起来就是一个容器,容器之间互相隔离,部署和迁移都非常方便。
Docker Compose 则是 Docker 官方提供的编排工具,通过一个 docker-compose.yml 文件即可定义并启动多个相互依赖的容器,特别适合本地开发、测试和小型生产场景。
重要本教程以 Ubuntu / Debian 系列发行版为例,其他 Linux 发行版或 Windows、macOS 可参考官方文档调整安装命令。
二、安装 Docker
1. 通过 APT 安装
sudo apt updatesudo apt install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyringscurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgsudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt updatesudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin2. 启动并设置开机自启
sudo systemctl enable --now dockersudo systemctl status docker3. 让非 root 用户也能使用 Docker
sudo usermod -aG docker $USERnewgrp docker提示执行
newgrp docker后当前终端即可生效,其他已打开的终端需要重新登录才能使用。
4. 验证安装
docker --versiondocker compose version三、Docker 核心概念
| 概念 | 说明 |
|---|---|
| 镜像(Image) | 容器运行的只读模板,包含应用代码、依赖和运行环境 |
| 容器(Container) | 镜像的运行实例,互相隔离,拥有独立的文件系统、网络和进程空间 |
| Dockerfile | 定义如何构建镜像的文本文件 |
| 数据卷(Volume) | 持久化容器数据的机制,数据保存在宿主机上,容器删除后仍然存在 |
| 网络(Network) | 容器之间通信的虚拟网络,同一网络内的容器可以通过服务名互相访问 |
四、Docker 常用命令
1. 镜像管理
docker pull ubuntu:22.04docker imagesdocker rmi ubuntu:22.04docker build -t myapp:1.0 .2. 容器生命周期
docker run -d --name web -p 8080:80 nginxdocker psdocker ps -adocker stop webdocker start webdocker restart webdocker rm webdocker rm -f web提示
docker run常用参数说明:
-d:后台运行--name:为容器指定名称-p 宿主机端口:容器端口:端口映射-v 宿主机路径:容器路径:挂载数据卷-e KEY=VALUE:设置环境变量--restart unless-stopped:自动重启策略
3. 进入容器与查看日志
docker exec -it web bashdocker logs -f webdocker inspect web4. 清理资源
docker system prunedocker volume prunedocker image prune注意
docker system prune会删除停止的容器、未被使用的网络、 dangling 镜像等,执行前请确认没有需要保留的容器或数据。
五、Dockerfile 示例
以一个简单的 Node.js 应用为例,项目目录结构如下:
my-node-app/├── Dockerfile├── .dockerignore├── package.json└── server.jsDockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"].dockerignore:
node_modulesnpm-debug.log.git.envDockerfile.dockerignore构建并运行:
cd my-node-appdocker build -t my-node-app:1.0 .docker run -d --name myapp -p 3000:3000 my-node-app:1.0六、Docker Compose 简介
Docker Compose 通过一个 YAML 文件描述多个容器之间的关系,例如依赖、网络、数据卷、环境变量等。只需要一条命令就可以启动或停止整个应用栈。
现代 Docker 已将 Compose 作为插件集成到 docker 命令中,命令格式为:
docker compose up -d旧版的独立命令 docker-compose 目前仍可使用,但推荐统一使用 docker compose。
七、安装 Docker Compose 插件
如果你按照前面的步骤安装了 docker-compose-plugin,则无需额外安装。否则可以单独安装:
sudo apt install docker-compose-plugin验证:
docker compose version八、docker-compose.yml 文件结构
一份常用的 docker-compose.yml 文件主要包含以下字段:
services: web: image: nginx:latest container_name: web ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html networks: - mynet depends_on: - db restart: unless-stopped
db: image: postgres:16 container_name: db environment: POSTGRES_USER: user POSTGRES_PASSWORD: password POSTGRES_DB: mydb volumes: - db_data:/var/lib/postgresql/data networks: - mynet
volumes: db_data:
networks: mynet:提示
services下定义每个容器depends_on只控制启动顺序,不保证服务已就绪volumes下声明命名卷,防止数据随容器删除而丢失- 同一
networks内的容器可以通过服务名互相访问
九、常用 Compose 命令
docker compose up -ddocker compose downdocker compose psdocker compose logs -fdocker compose exec web bashdocker compose restartdocker compose builddocker compose pull注意
docker compose down默认会删除容器和网络,但保留数据卷。如果需要一并删除卷,请使用docker compose down -v。
十、完整示例:部署一个 Web 应用 + 数据库
1. 项目结构
demo-project/├── docker-compose.yml├── Dockerfile├── .dockerignore├── package.json└── server.js2. 应用代码
server.js:
const express = require('express');const { Pool } = require('pg');
const app = express();const pool = new Pool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: 5432,});
app.get('/', async (req, res) => { const result = await pool.query('SELECT NOW()'); res.json({ time: result.rows[0].now });});
app.listen(3000, () => { console.log('Server is running on port 3000');});package.json:
{ "name": "demo-project", "version": "1.0.0", "dependencies": { "express": "^4.18.0", "pg": "^8.11.0" }, "scripts": { "start": "node server.js" }}3. Dockerfile
FROM node:20-alpineWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .EXPOSE 3000CMD ["node", "server.js"]4. docker-compose.yml
services: web: build: . container_name: demo-web ports: - "3000:3000" environment: DB_HOST: db DB_USER: demo DB_PASSWORD: demopass DB_NAME: demo networks: - demonet depends_on: - db restart: unless-stopped
db: image: postgres:16-alpine container_name: demo-db environment: POSTGRES_USER: demo POSTGRES_PASSWORD: demopass POSTGRES_DB: demo volumes: - db_data:/var/lib/postgresql/data networks: - demonet restart: unless-stopped
volumes: db_data:
networks: demonet:5. 启动与验证
cd demo-projectdocker compose up -ddocker compose psdocker compose logs -fcurl http://localhost:3000停止并清理:
docker compose down如果需要同时删除数据库卷,请执行:
docker compose down -v十一、常见问题与注意事项
1. 数据持久化
容器本身是临时的,数据应通过 volumes 或绑定挂载保存到宿主机。数据库类服务强烈建议使用命名卷,避免 docker compose down 误删后数据丢失。
2. 端口冲突
ports 中左侧是宿主机端口,右侧是容器端口。如果左侧端口已被占用,docker compose up 会失败,请更换为未被使用的端口。
3. 环境变量管理
对于敏感信息,建议通过 .env 文件管理,而不是直接写在 docker-compose.yml 中。Compose 会自动读取同目录下的 .env 文件。
DB_PASSWORD=your_secret_passwordenvironment: DB_PASSWORD: ${DB_PASSWORD}4. 镜像清理
长期开发会积累大量镜像,可以定期清理:
docker image prune -a注意
docker image prune -a会删除所有未被任何容器使用的镜像,请确认不再需要这些镜像后再执行。
5. 容器内时间
容器默认使用 UTC 时间,如果需要同步宿主机时区,可以挂载:
volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro十二、总结
Docker 让应用交付变得轻量和一致,Docker Compose 则让多容器应用的本地开发和部署变得简单。掌握镜像构建、容器生命周期、数据卷、网络和 Compose 编排后,就可以快速搭建稳定、可移植的服务环境。