Docker容器化部署教程:从入门到项目实战

Docker 容器化部署教程封面:从入门到项目实战,包含 Docker 鲸鱼图标、容器镜像与代码部署视觉设计

前言

第一次听到”Docker”这个词的时候,你是不是也像我一样觉得这是个很高深的东西?我当初也是这么想的,甚至还把它和码头工人(docker本身就是这个词)联系在一起,觉得这东西肯定跟搬运货物有关。

后来真正用了才发现,Docker其实就是程序员用来”装软件”的神器——它能让你把应用程序和它需要的所有依赖打包在一起,不管你电脑是什么系统,装上Docker就能跑起来。再也不用听”在我这儿能跑啊”这种话了。

今天这篇文章,就是给完全没接触过Docker的小白写的。我会从最基础的概念讲起,手把手带你走完Docker入门的所有步骤。即使你是第一次接触容器技术,跟着这篇文章也能快速上手。

Docker 核心概念示意图:镜像、容器、仓库关系图解,搭配命令行与项目部署流程展示

什么是Docker?

一句话解释Docker

简单来说,Docker就是一个容器技术。容器是什么?想象一下集装箱——不管里面装的是衣服还是电器,用集装箱运输,到哪儿都能原封不动地卸下来。Docker容器就是这个”集装箱”,把你的代码和运行环境打包在一起,确保”在我这儿能跑,到你那儿也能跑”。

这个比喻非常贴切。你想想,传统软件开发中,开发人员经常遇到这样的问题:

“代码在我电脑上是好的啊,为什么到你那儿就报错了?”

“我装的是Python 3.8,你的怎么是3.6?”

“缺少xxx.dll文件,请重新安装”——经典的DLL地狱

这些问题的根源就是环境不一致。Docker通过容器化技术,把你的应用和它所需的一切(代码、运行时、系统工具、系统库)全部打包,从根本上解决了这个问题。

Docker和虚拟机的区别

你可能用过虚拟机,比如VMware或者VirtualBox。虚拟机就像是在你电脑里再装一台完整的电脑,要分配内存、硬盘,还要装操作系统,占用资源大,启动也慢。

Docker容器则不一样,它直接复用你电脑的系统内核,只是把你的应用和依赖隔离出来。打个比方:

  • 虚拟机就像买了一套房子,里面有完整的厨房、卧室、卫生间
  • Docker容器就像租了一个单间,只需要和其他租客共享厨房和卫生间
特性虚拟机Docker容器
启动时间几分钟几秒钟
占用空间几个GB几十到几百MB
资源消耗
隔离性完全隔离共享内核
操作系统完整系统共享宿主机内核

Docker的应用场景

Docker在实际工作中有非常多的应用场景:

1. 开发和测试环境统一

团队里十个人,可能有人用Windows,有人用Mac,有人用Ubuntu。如果每个人都按自己的方式搭建开发环境,那”环境问题”就会成为开发的最大障碍。

用Docker后,大家使用相同的容器镜像,确保每个人的开发环境完全一致。

2. 持续集成和持续部署(CI/CD)

在自动化部署中,Docker可以把应用打包成镜像,推送到服务器,然后用同样的镜像启动容器。整个过程可重复、可追溯。

3. 微服务架构

微服务把一个大应用拆成多个小服务,每个服务独立开发、独立部署。每个微服务可以打包成一个或多个Docker容器,灵活扩展。

4. 快速搭建学习环境

想学Redis?直接docker run redis。想学MySQL?docker run mysql。再也不用担心安装配置问题。

Docker核心概念详解

在深入实践之前,我们先来理解Docker的三个核心概念:镜像(Image)容器(Container)和仓库(Repository)

镜像

镜像你可以理解成是一个”模具”,它定义了运行某个应用需要的所有东西:

  • 代码和依赖
  • 系统工具和库
  • 环境变量
  • 配置文件

镜像是只读的,一旦创建就不能修改。就像一个模具,可以用来铸造出多个相同的铸件。

常见的镜像命名格式是镜像名:标签,比如:

  • ubuntu:20.04 – Ubuntu操作系统的20.04版本
  • python:3.11 – Python 3.11运行环境
  • nginx:latest – 最新版本的Nginx

容器

容器就是镜像的”实例”。你可以把镜像理解成类,容器理解成对象——类是用来定义模板的,对象是真正在运行的实体。

同一个镜像可以创建多个容器,每个容器都是独立的。

仓库

仓库就是存储和分发镜像的地方。最常用的就是Docker Hub,它是Docker官方维护的”应用商店”,里面有海量的官方镜像和社区镜像。

类比一下:

  • 镜像就像软件
  • 仓库就像应用商店

安装Docker

Windows系统

  1. 确认系统要求
    • Windows 10专业版/企业版或更高(需要支持WSL2)
    • 开启BIOS虚拟化(VT-x/AMD-V)

  2. 下载Docker Desktop
    访问官网下载:https://www.docker.com/products/docker-desktop
  3. 安装
    • 双击安装包,按提示一路下一步
    • 安装程序会自动启用WSL2和Hyper-V

  4. 验证安装
    安装完成后,Docker会自动启动,你会在任务栏看到一个鲸鱼图标。右键点击图标,选择”Dashboard”可以打开Docker管理界面。

macOS系统

  1. 下载Docker Desktop for Mac
    官网下载对应芯片版本(Apple M1/M2用ARM64版,Intel芯片用AMD64版)
  2. 安装
    • 把Docker拖到Applications文件夹
    • 首次启动可能需要输入密码授权

  3. 验证
    打开终端,输入docker version,看到版本信息就说明安装成功了。

Linux系统(Ubuntu为例)

bash

# 更新apt源
sudo apt-get update

# 安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release

# 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 添加Docker仓库
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 把当前用户加入docker组(避免每次sudo)
sudo usermod -aG docker $USER

# 验证安装
docker run hello-world

第一个Docker容器

安装完成后,我们来运行第一个容器,感受一下Docker的神奇之处。

打开终端(Windows打开PowerShell或CMD),输入:

bash

docker run hello-world

如果一切正常,你会看到类似这样的输出:

plaintext

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete 
Digest: sha256:abc123...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.

这行命令做了三件事:

  1. 检查本地是否有hello-world镜像
  2. 没有的话,从Docker Hub下载(Pull)
  3. 用这个镜像创建并启动一个容器

Docker常用命令

镜像相关命令

bash

# 查看本地所有镜像
docker images

# 搜索镜像
docker search nginx

# 下载镜像
docker pull nginx:latest

# 删除镜像
docker rmi nginx:latest

# 构建镜像(后面会详细讲)
docker build -t my-app .

容器相关命令

bash

# 列出正在运行的容器
docker ps

# 列出所有容器(包括已停止的)
docker ps -a

# 启动容器
docker start container_id

# 停止容器
docker stop container_id

# 重启容器
docker restart container_id

# 删除容器
docker rm container_id

# 进入容器内部(类似SSH登录)
docker exec -it container_id /bin/bash

# 查看容器日志
docker logs container_id

# 实时查看日志
docker logs -f container_id

实战:部署一个Python Web应用

光说不练假把式,现在我们来实战一下,用Docker部署一个Flask Web应用。

步骤1:创建项目结构

首先创建一个项目文件夹:

bash

mkdir my-web-app
cd my-web-app

在文件夹里创建以下文件:

app.py – 我们的Web应用:

python

from flask import Flask, jsonify
import os
import socket

app = Flask(__name__)

@app.route('/')
def hello():
    name = os.environ.get('NAME', 'Developer')
    hostname = socket.gethostname()
    return f'''
    <h1>Hello {name}!</h1>
    <p>Welcome to Docker!</p>
    <p>Hostname: {hostname}</p>
    '''

@app.route('/api/health')
def health():
    return jsonify({
        'status': 'healthy',
        'service': 'my-web-app'
    })

@app.route('/api/info')
def info():
    return jsonify({
        'python_version': os.sys.version,
        'platform': os.name
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

requirements.txt – Python依赖:

plaintext

flask==2.3.0
gunicorn==20.1.0

Dockerfile – 这是关键文件,定义了我们如何构建镜像:

dockerfile

# 指定基础镜像
FROM python:3.11-slim

# 设置工作目录
WORKDIR /app

# 复制依赖文件到容器
COPY requirements.txt .

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制应用代码
COPY app.py .

# 设置环境变量
ENV NAME=Developer
ENV FLASK_ENV=production

# 暴露端口
EXPOSE 5000

# 启动命令(生产环境用gunicorn)
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]

步骤2:构建镜像

在项目文件夹里运行:

bash

docker build -t my-web-app .

-t参数给镜像起个名字,后面的.表示Dockerfile在当前目录。

构建过程会输出很多日志,耐心等待即可。完成后用docker images查看:

bash

docker images

# 输出类似:
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
my-web-app   latest    a1b2c3d4e5f6   10 seconds ago  150MB
python       3.11-slim a1b2c3d4e5f7   3 days ago      150MB

步骤3:运行容器

bash

# 前台运行(方便查看日志)
docker run -p 5000:5000 --name my-app my-web-app

# 或后台运行
docker run -d -p 5000:5000 --name my-app my-web-app

参数说明:

  • -d:后台运行(detached模式)
  • -p 5000:5000:把容器的5000端口映射到主机的5000端口
  • --name my-app:给容器起个名字
  • my-web-app:使用哪个镜像

现在打开浏览器访问http://localhost:5000,你应该能看到欢迎页面。

步骤4:常用操作

bash

# 查看运行中的容器
docker ps

# 查看所有容器
docker ps -a

# 停止容器
docker stop my-app

# 启动已停止的容器
docker start my-app

# 重启容器
docker restart my-app

# 查看容器日志
docker logs my-app

# 实时查看日志
docker logs -f my-app

# 删除容器
docker rm my-app

# 查看容器详细信息
docker inspect my-app

Docker Compose:管理多容器应用

当你需要运行多个容器时(比如Web应用+数据库+缓存),一个个启动就很麻烦了。Docker Compose就是来解决这个问题的。

安装Docker Compose

Docker Desktop已经自带了Docker Compose。如果你用的是Linux:

bash

sudo apt-get install docker-compose

或者使用插件版本(推荐):

bash

sudo apt-get install docker-compose-plugin

创建docker-compose.yml

在项目目录创建docker-compose.yml

yaml

version: '3.8'

services:
  web:
    build: .
    ports:
      - "5000:5000"
    environment:
      - NAME=Developer
      - REDIS_HOST=redis
    volumes:
      - .:/app
    depends_on:
      - redis
    restart: unless-stopped
  
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    restart: unless-stopped

volumes:
  redis-data:

这个配置定义了两个服务:

  • web:我们的Python应用
  • redis:Redis缓存服务

使用Docker Compose

bash

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 停止所有服务
docker-compose down

# 重新构建并启动
docker-compose up --build -d

# 只启动某个服务
docker-compose up -d redis

Docker Hub:分享和获取镜像

Docker Hub是Docker官方维护的镜像仓库,里面有海量的官方镜像和社区镜像。

常用官方镜像

镜像名说明使用场景
nginxWeb服务器静态网站、反向代理
redis内存数据库缓存、Session存储
mysqlMySQL数据库关系型数据存储
postgresPostgreSQL数据库高级关系型数据存储
mongoMongoDB数据库文档型数据存储
nodeNode.js运行环境JavaScript后端开发
pythonPython运行环境Python开发
postgresPostgreSQL数据库企业级数据库

部署一个完整博客系统

光跑个Hello World还不够过瘾,我们来部署一个真实的博客系统——Ghost。

bash

docker run -d \
  --name ghost-blog \
  -p 3001:2368 \
  -e NODE_ENV=production \
  -e url=http://localhost:3001 \
  -e mail__transport=SMTP \
  -e mail__options__host=smtp.example.com \
  -e mail__options__port=587 \
  -e mail__options__auth__user=you@example.com \
  -e mail__options__auth__pass=yourpassword \
  ghost:latest

现在访问http://localhost:3001/ghost,你就能看到Ghost博客的管理界面了!

进阶:优化Dockerfile

写Dockerfile也是有讲究的,好的Dockerfile能让镜像更小、构建更快。

使用多阶段构建

dockerfile

# 第一阶段:构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 第二阶段:运行
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

多阶段构建可以显著减小最终镜像大小,因为构建工具不会被包含在最终镜像中。

使用.dockerignore

在项目根目录创建.dockerignore文件,排除不需要的文件:

plaintext

node_modules
.git
.gitignore
*.md
Dockerfile
.dockerignore
.env*
npm-debug.log

镜像大小优化技巧

  1. 使用合适的基础镜像:Alpine镜像比Ubuntu小很多
  2. 合并RUN指令:减少镜像层数
  3. 清理缓存:pip安装后删除缓存
  4. 使用多阶段构建:分离构建和运行环境

常见问题解答

1. Docker下载镜像太慢怎么办?

配置国内镜像加速。在Docker Desktop设置中添加镜像源:

或者编辑/etc/docker/daemon.json(Linux):

json

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

修改后重启Docker服务:

bash

sudo systemctl restart docker

2. 容器里改文件后,主机上看不到?

使用数据卷挂载:

bash

docker run -v /path/on/host:/path/in/container ...

这样容器内的文件和主机实时同步,修改立即生效。

3. 容器怎么和主机网络通信?

Docker会创建一个虚拟网络(bridge网络),默认情况下:

  • 容器之间可以通过容器名互相访问
  • 容器可以通过网关访问主机和外网
  • 主机通过端口映射访问容器

4. 如何在容器内使用GPU?

安装nvidia-container-toolkit:

bash

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update
sudo apt-get install nvidia-container-toolkit
sudo systemctl restart docker

然后运行时加上--gpus all参数:

bash

docker run --gpus all nvidia/cuda:11.0-base nvidia-smi

5. 容器自动退出了怎么办?

检查日志找出原因:

bash

docker logs container_id

常见原因:

  • 应用代码报错
  • 缺少环境变量
  • 端口被占用
  • 配置文件错误

总结

Docker其实没那么可怕,它就是一个帮你管理”装软件”问题的工具。通过今天的教程,你应该已经掌握了:

  • Docker的基本概念(镜像、容器、仓库)
  • 安装Docker的不同平台方法
  • 构建自己的Docker镜像
  • 运行和管理容器
  • 使用Docker Compose管理多容器应用
  • Dockerfile的优化技巧
  • 常见问题的解决方法

Docker是现代云原生开发的基础,学会它你就迈出了成为DevOps工程师的第一步。不管你是前端、后端还是运维工程师,了解Docker都能让你的工作更加高效。

相关推荐

Docker,让”在我这儿能跑”不再是问题!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注