docker从入门到实践的全面教程

引言

在现代软件开发和部署流程中,Docker已经成为一个无法忽视的重要工具。它彻底改变了我们构建、测试和部署应用的方式。无论你是刚接触DevOps的新手,还是希望优化现有部署流程的经验丰富的开发者,Docker都能为你提供一种标准化、高效的方式来管理应用及其依赖。

今天,我们将深入探讨Docker部署的全过程,从基础概念到实际操作,帮助你掌握这项强大技术的精髓。准备好了吗?让我们开始吧!

Docker基础知识

什么是Docker?

Docker是一个开源平台,允许开发者使用容器来构建、部署和运行应用程序。容器是轻量级的、独立的、可执行的软件包,包含了运行应用所需的一切:代码、运行环境、系统工具、系统库和设置。

与传统虚拟机不同,Docker容器共享主机系统的内核,但在用户空间中运行隔离的进程。这使得容器启动速度快、资源消耗低,同时保持了良好的隔离性。

Docker的核心概念

在深入Docker部署前,有几个关键概念需要理解:

  1. 镜像(Image) - 只读模板,包含创建Docker容器的指令。可以理解为应用程序的"安装包"。
  2. 容器(Container) - 镜像的运行实例,可以被创建、启动、停止、删除和暂停。
  3. Dockerfile - 用于构建镜像的文本文件,包含一系列指令和参数。
  4. Docker Registry - 存储Docker镜像的仓库,Docker Hub是最常用的公共仓库。
  5. Docker Compose - 用于定义和运行多容器Docker应用的工具。

Docker的安装

在开始部署前,首先需要安装Docker。安装过程因操作系统而异,下面简要介绍几个主流系统的安装方法:

Ubuntu安装Docker

复制代码
# 更新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

# 设置稳定版仓库
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 Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

CentOS安装Docker

复制代码
# 安装所需的包
sudo yum install -y yum-utils

# 设置仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装Docker Engine
sudo yum install docker-ce docker-ce-cli containerd.io

# 启动Docker
sudo systemctl start docker

macOS安装Docker

最简单的方法是下载并安装Docker Desktop for Mac。它包含了Docker Engine、Docker CLI客户端、Docker Compose等组件。

Windows安装Docker

Windows用户可以下载Docker Desktop for Windows,同样包含了所有必要的组件。

安装完成后,可以通过以下命令验证安装:

复制代码
docker --version
docker-compose --version

创建第一个Docker镜像

现在我们已经安装了Docker,接下来通过一个简单的例子来创建第一个Docker镜像。

假设我们要部署一个简单的Node.js应用,首先创建一个新目录并初始化项目:

复制代码
mkdir docker-node-app
cd docker-node-app
npm init -y

创建一个简单的服务器文件app.js

复制代码
const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World from Docker!\n');
});

const port = process.env.PORT || 3000;
server.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

接下来,创建一个Dockerfile(注意大小写,没有扩展名):

复制代码
# 使用官方Node.js 14镜像作为基础镜像
FROM node:14-alpine

# 设置工作目录
WORKDIR /app

# 复制package.json和package-lock.json
COPY package*.json ./

# 安装依赖
RUN npm install

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "app.js"]

现在,让我们构建这个镜像:

复制代码
docker build -t node-app .

构建完成后,可以使用以下命令列出所有镜像:

复制代码
docker images

你应该能看到刚创建的node-app镜像。

运行Docker容器

有了镜像后,可以启动一个容器来运行应用:

复制代码
docker run -p 3000:3000 -d --name my-node-app node-app

这个命令中: - -p 3000:3000 将容器的3000端口映射到主机的3000端口 - -d 在后台运行容器 - --name my-node-app 给容器命名 - node-app 使用的镜像名

现在可以通过访问http://localhost:3000来查看应用是否正常运行。

查看正在运行的容器:

复制代码
docker ps

如果需要查看容器日志:

复制代码
docker logs my-node-app

停止和删除容器:

复制代码
docker stop my-node-app
docker rm my-node-app

使用Docker Compose部署多容器应用

在实际应用中,我们通常需要同时运行多个相互关联的服务,如Web应用、数据库、缓存等。Docker Compose就是为解决这个问题而生的。

创建一个docker-compose.yml文件:

复制代码
version: '3'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
    environment:
      - DATABASE_URL=mongodb://db:27017/myapp

  db:
    image: mongo:4.4
    volumes:
      - mongodb_data:/data/db

volumes:
  mongodb_data:

这个配置定义了两个服务: - web - 我们的Node.js应用 - db - MongoDB数据库

使用以下命令启动这些服务:

复制代码
docker-compose up -d

要停止并移除容器:

复制代码
docker-compose down

如果还想移除卷(会删除数据):

复制代码
docker-compose down -v

Docker部署最佳实践

1. 保持镜像尽可能小

使用合适的基础镜像(如alpine版本)并清理不必要的文件:

复制代码
FROM node:14-alpine

WORKDIR /app
COPY package*.json ./
RUN npm install --production && npm cache clean --force
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

2. 分层构建

利用Docker的缓存机制,合理组织Dockerfile中的指令顺序,将变化较少的内容放在前面:

复制代码
# 第一阶段:构建
FROM node:14-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 第二阶段:运行
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm install --production
EXPOSE 3000
CMD ["node", "dist/main.js"]

3. 使用.dockerignore文件

创建.dockerignore文件,排除不需要复制到镜像中的文件:

复制代码
node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
.github
.gitignore
README.md

4. 非root用户运行容器

在Dockerfile中添加专用用户,提高安全性:

复制代码
FROM node:14-alpine

# 创建应用目录
WORKDIR /app

# 复制应用文件
COPY . .

# 安装依赖
RUN npm install --production

# 创建非root用户
RUN addgroup -g 1000 appuser && \
    adduser -u 1000 -G appuser -s /bin/sh -D appuser

# 修改应用目录权限
RUN chown -R appuser:appuser /app

# 切换到非root用户
USER appuser

EXPOSE 3000
CMD ["node", "app.js"]

5. 使用Docker健康检查

复制代码
FROM node:14-alpine
WORKDIR /app
COPY . .
RUN npm install --production
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "app.js"]

在生产环境中部署Docker

在生产环境部署Docker应用时,有几种常见的方法:

1. 直接在服务器上使用Docker Compose

这是最简单的方法,适用于小型应用或单服务器部署:

  1. 将代码和docker-compose.yml文件推送到服务器
  2. 登录服务器,导航到项目目录
  3. 运行docker-compose up -d

2. 使用Docker Swarm进行集群部署

Docker Swarm是Docker的原生集群解决方案:

  1. 初始化Swarm:

    docker swarm init --advertise-addr <MANAGER-IP>

  2. 添加工作节点(在其他服务器上执行):

    docker swarm join --token <TOKEN> <MANAGER-IP>:2377

  3. 部署服务:

    docker stack deploy -c docker-compose.yml my-app

3. 使用Kubernetes进行大规模部署

对于更复杂的部署,Kubernetes提供了强大的容器编排能力:

  1. 创建Kubernetes集群(可以使用如AWS EKS、Google GKE或自建集群)

  2. 编写Kubernetes配置文件(Deployment, Service, ConfigMap等)

  3. 使用kubectl应用配置:

    kubectl apply -f k8s/

持续集成与部署(CI/CD)

Docker非常适合CI/CD流程。下面是使用GitHub Actions自动构建和部署Docker应用的简单示例:

创建.github/workflows/docker-deploy.yml文件:

复制代码
name: Docker Build and Deploy

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: yourusername/app:latest

      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /path/to/app
            docker-compose pull
            docker-compose up -d

监控与日志管理

部署应用后,监控和日志管理至关重要:

1. 使用Prometheus和Grafana监控容器

复制代码
version: '3'
services:
  app:
    image: yourusername/app:latest
    ports:
      - "3000:3000"

  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana
    depends_on:
      - prometheus
    ports:
      - "3001:3000"

2. 使用ELK Stack或Loki进行日志管理

复制代码
version: '3'
services:
  app:
    image: yourusername/app:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"

  promtail:
    image: grafana/promtail:latest
    volumes:
      - /var/lib/docker/containers:/var/lib/docker/containers
      - ./promtail-config.yml:/etc/promtail/config.yml

结语

Docker部署为应用提供了一种强大、灵活且一致的方式,使得从开发到生产的过程更加顺畅。通过本文介绍的基础知识、最佳实践和部署策略,你应该能够开始在自己的项目中利用Docker的强大功能。

当然,Docker世界非常广阔,这里只是冰山一角。随着你越来越熟悉Docker,可以进一步探索高级主题,如Docker安全、自定义网络、多阶段构建、Kubernetes部署等。

记住,容器化不仅仅是技术选择,更是一种思维方式的转变。拥抱这种变化,将为你的开发和部署流程带来显著的改进!

相关推荐
@PHARAOH3 小时前
HOW - 本地基于 docker 快速构建 mysql 数据库
数据库·mysql·docker
叁金Coder3 小时前
【Centos8 环境下 X86 版本 docker-29.1.3 的安装配置】
运维·docker·容器
SuniaWang3 小时前
Docker Compose 容器管理与自动化部署进阶指南
docker·容器·自动化
kaixin_啊啊3 小时前
(1)如何使用Docker部署IT-Tools并结合内网穿透实现公网访问本地工具箱服务
docker·容器·eureka
陈皮糖..4 小时前
Docker Compose 学习之多容器应用编排与运维实践 —— 基于 Nginx+MySQL+Redis 服务栈的部署与管理
运维·redis·学习·mysql·nginx·docker
程序员老赵4 小时前
踩坑必看!配置了 Docker 镜像源,为啥还在疯狂访问官方仓库?
docker·容器
春日见4 小时前
车载系统中的CPU与内存监管
java·开发语言·驱动开发·docker·计算机外设
程序员柳4 小时前
智能学生管理系统:Spring Boot3+Vue3 前后端分离开发与 Docker 部署
spring boot·后端·docker