【docker基础】第十二周:综合实战项目

📚前言

👀回顾,系统学习docker系列已发布内容:

【docker基础】0、系统学习docker之总计划

【docker基础】第一课、从零开始理解容器技术

【docker基础】第二课:安装、配置与基础命令

【docker基础】第三课:镜像管理与Dockerfile基础

【docker基础】第四课:容器操作与数据管理

【docker基础】第五课:Docker网络详解-CSDN博客

【docker基础】第六课:Web应用与数据库容器部署-CSDN博客

【docker基础】 第七课:Docker Compose 多容器实战-CSDN博客

【docker基础】 第八周:容器监控与应用更新策略-CSDN博客

【docker基础】第九周:Docker安全与镜像优化-CSDN博客

【docker基础】Docker第十周:CI/CD集成-CSDN博客

【docker基础】第十一周:容器编排基础-CSDN博客

🔗相关文档:

windows下安装docker

【docker基础】Ubuntu 安装 Docker 超详细小白教程

📒本课学习目标:

  1. 项目架构设计:前端 + 后端 + 数据库 + 缓存
  2. 多服务开发:Node.js API + Vue.js 前端
  3. 配置文件:MySQL、Redis、Nginx
  4. 环境配置:开发环境和生产环境
  5. 资源限制:CPU、内存限制
  6. 监控日志:日志轮转、健康检查
  7. 部署流程:构建、推送、部署
  8. 性能优化:网络、存储、缓存优化

🌍Docker第十二周:综合实战项目

欢迎来到 Docker 第十二周的学习!本周我们将进行一个完整的实战项目,从代码开发到容器化部署,完成一个真实的生产级应用部署流程。


第一章:项目概述

1.1 项目架构

我们将部署一个完整的博客系统,包含以下组件:

复制代码
┌─────────────────────────────────────────────────────────────┐
│                        用户请求                              │
│                    http://example.com                       │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ↓
┌─────────────────────────────────────────────────────────────┐
│                    Nginx 反向代理                           │
│                    (负载均衡 + SSL)                         │
└───────────────────────────┬─────────────────────────────────┘
                            │
        ┌───────────────────┼───────────────────┐
        ↓                   ↓                   ↓
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│  Web Server 1 │   │  Web Server 2 │   │  Web Server 3 │
│   (Nginx)     │   │   (Nginx)     │   │   (Nginx)     │
└───────┬───────┘   └───────┬───────┘   └───────┬───────┘
        │                   │                   │
        └───────────────────┼───────────────────┘
                            │
                            ↓
┌─────────────────────────────────────────────────────────────┐
│                    应用服务器 (Node.js)                     │
│                    API 服务集群                             │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ↓
┌─────────────────────────────────────────────────────────────┐
│                    Redis 缓存服务器                         │
│                    (会话 + 热点数据)                        │
└─────────────────────────────────────────────────────────────┘
                            │
                            ↓
┌─────────────────────────────────────────────────────────────┐
│                    MySQL 数据库                             │
│                    (主从复制)                               │
└─────────────────────────────────────────────────────────────┘

1.2 技术栈

组件 技术 说明
前端 Vue.js 单页应用
后端 Node.js + Express REST API
数据库 MySQL 5.7 关系型数据库
缓存 Redis 会话和缓存
Web服务器 Nginx 反向代理
容器编排 Docker Compose 本地开发
CI/CD GitHub Actions 自动部署

第二章:项目结构

2.1 目录结构

复制代码
blog-app/
├── frontend/                  # 前端代码
│   ├── src/
│   ├── public/
│   ├── Dockerfile
│   └── package.json
├── backend/                   # 后端代码
│   ├── src/
│   ├── Dockerfile
│   └── package.json
├── nginx/                     # Nginx 配置
│   ├── nginx.conf
│   └── conf.d/
│       └── blog.conf
├── mysql/                     # MySQL 配置
│   └── init.sql
├── redis/                     # Redis 配置
│   └── redis.conf
├── monitoring/                # 监控配置
│   └── prometheus.yml
├── docker-compose.yml         # 开发环境
├── docker-compose.prod.yml    # 生产环境
└── .env                       # 环境变量

2.2 创建项目目录

复制代码
mkdir -p ~/blog-app/{frontend,backend,nginx/conf.d,mysql,redis,monitoring}
cd ~/blog-app

第三章:后端服务开发

3.1 创建后端项目

backend/package.json

复制代码
{
  "name": "blog-api",
  "version": "1.0.0",
  "description": "Blog API Server",
  "main": "src/index.js",
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mysql2": "^3.6.0",
    "redis": "^4.6.0",
    "cors": "^2.8.5",
    "dotenv": "^16.3.1"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}

3.2 后端代码

backend/src/index.js

复制代码
const express = require('express');
const cors = require('cors');
const mysql = require('mysql2/promise');
const redis = require('redis');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件
app.use(cors());
app.use(express.json());

// MySQL 连接池
const db = mysql.createPool({
  host: process.env.DB_HOST || 'mysql',
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME || 'blog',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// Redis 客户端
const redisClient = redis.createClient({
  url: `redis://${process.env.REDIS_HOST || 'redis'}:${process.env.REDIS_PORT || 6379}`
});

redisClient.on('error', (err) => console.log('Redis Client Error', err));
redisClient.connect().then(() => console.log('Redis Connected'));

// 健康检查
app.get('/health', async (req, res) => {
  try {
    await db.query('SELECT 1');
    res.json({ status: 'healthy', timestamp: new Date().toISOString() });
  } catch (error) {
    res.status(500).json({ status: 'unhealthy', error: error.message });
  }
});

// 获取文章列表(带缓存)
app.get('/api/articles', async (req, res) => {
  try {
    // 尝试从缓存获取
    const cached = await redisClient.get('articles:list');
    if (cached) {
      return res.json(JSON.parse(cached));
    }

    // 从数据库获取
    const [rows] = await db.query('SELECT * FROM articles ORDER BY created_at DESC');
    
    // 存入缓存(60秒)
    await redisClient.setEx('articles:list', 60, JSON.stringify(rows));
    
    res.json(rows);
  } catch (error) {
    console.error('Error fetching articles:', error);
    res.status(500).json({ error: 'Failed to fetch articles' });
  }
});

// 获取单篇文章
app.get('/api/articles/:id', async (req, res) => {
  try {
    const { id } = req.params;
    
    // 尝试从缓存获取
    const cached = await redisClient.get(`articles:${id}`);
    if (cached) {
      return res.json(JSON.parse(cached));
    }

    // 从数据库获取
    const [rows] = await db.query('SELECT * FROM articles WHERE id = ?', [id]);
    
    if (rows.length === 0) {
      return res.status(404).json({ error: 'Article not found' });
    }

    // 存入缓存
    await redisClient.setEx(`articles:${id}`, 300, JSON.stringify(rows[0]));
    
    res.json(rows[0]);
  } catch (error) {
    console.error('Error fetching article:', error);
    res.status(500).json({ error: 'Failed to fetch article' });
  }
});

// 创建文章
app.post('/api/articles', async (req, res) => {
  try {
    const { title, content, author } = req.body;
    
    const [result] = await db.query(
      'INSERT INTO articles (title, content, author) VALUES (?, ?, ?)',
      [title, content, author]
    );

    // 清除列表缓存
    await redisClient.del('articles:list');

    res.status(201).json({ id: result.insertId, message: 'Article created' });
  } catch (error) {
    console.error('Error creating article:', error);
    res.status(500).json({ error: 'Failed to create article' });
  }
});

// 启动服务器
app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server running on port ${PORT}`);
});

3.3 后端 Dockerfile

backend/Dockerfile

复制代码
# 使用 Node.js Alpine 镜像(减小体积)
FROM node:18-alpine

# 创建应用目录
WORKDIR /app

# 复制 package 文件
COPY package*.json ./

# 安装依赖(使用缓存层)
RUN npm ci --only=production

# 复制应用代码
COPY src/ ./src/

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget -qO- http://localhost:3000/health || exit 1

# 启动命令
CMD ["node", "src/index.js"]

第四章:前端服务开发

4.1 前端代码

frontend/public/index.html

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客系统</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body { font-family: Arial, sans-serif; background: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; padding: 20px; }
        header { background: #333; color: white; padding: 20px; text-align: center; }
        header h1 { margin-bottom: 10px; }
        nav a { color: white; margin: 0 15px; text-decoration: none; }
        .article-list { margin-top: 30px; }
        .article-card { background: white; padding: 20px; margin-bottom: 20px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        .article-card h2 { color: #333; margin-bottom: 10px; }
        .article-meta { color: #666; font-size: 14px; margin-bottom: 10px; }
        .article-content { line-height: 1.6; color: #444; }
        .status { padding: 10px; background: #4CAF50; color: white; text-align: center; margin-bottom: 20px; border-radius: 4px; }
    </style>
</head>
<body>
    <header>
        <h1>博客系统</h1>
        <nav>
            <a href="#" onclick="loadArticles()">首页</a>
            <a href="#" onclick="showForm()">发布文章</a>
        </nav>
    </header>
    
    <div class="container">
        <div id="status" class="status" style="display: none;"></div>
        <div id="content"></div>
    </div>

    <script>
        const API_BASE = window.location.port === '8080' ? 'http://localhost:3000' : '/api';

        async function loadArticles() {
            const status = document.getElementById('status');
            const content = document.getElementById('content');
            
            try {
                status.style.display = 'block';
                status.textContent = '加载中...';
                status.style.background = '#2196F3';
                
                const response = await fetch(`${API_BASE}/articles`);
                const articles = await response.json();
                
                status.style.background = '#4CAF50';
                status.textContent = `共 ${articles.length} 篇文章`;
                
                content.innerHTML = articles.length === 0 
                    ? '<p>暂无文章</p>'
                    : articles.map(article => `
                        <div class="article-card">
                            <h2>${article.title}</h2>
                            <div class="article-meta">作者: ${article.author} | ${new Date(article.created_at).toLocaleString()}</div>
                            <div class="article-content">${article.content}</div>
                        </div>
                    `).join('');
            } catch (error) {
                status.style.background = '#f44336';
                status.textContent = '加载失败: ' + error.message;
            }
            
            setTimeout(() => { status.style.display = 'none'; }, 3000);
        }

        function showForm() {
            document.getElementById('content').innerHTML = `
                <div class="article-card">
                    <h2>发布新文章</h2>
                    <form onsubmit="submitArticle(event)">
                        <p style="margin-bottom: 10px;">
                            <input type="text" id="title" placeholder="标题" required style="width: 100%; padding: 10px;">
                        </p>
                        <p style="margin-bottom: 10px;">
                            <input type="text" id="author" placeholder="作者" required style="width: 100%; padding: 10px;">
                        </p>
                        <p style="margin-bottom: 10px;">
                            <textarea id="content" placeholder="内容" rows="5" required style="width: 100%; padding: 10px;"></textarea>
                        </p>
                        <p>
                            <button type="submit" style="padding: 10px 30px; background: #333; color: white; border: none; cursor: pointer;">发布</button>
                        </p>
                    </form>
                </div>
            `;
        }

        async function submitArticle(event) {
            event.preventDefault();
            const title = document.getElementById('title').value;
            const author = document.getElementById('author').value;
            const content = document.getElementById('content').value;
            
            try {
                const response = await fetch(`${API_BASE}/articles`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ title, author, content })
                });
                
                if (response.ok) {
                    alert('发布成功!');
                    loadArticles();
                }
            } catch (error) {
                alert('发布失败: ' + error.message);
            }
        }

        window.onload = loadArticles;
    </script>
</body>
</html>

4.2 前端 Dockerfile

frontend/Dockerfile

复制代码
# 多阶段构建
# 阶段1:构建
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 阶段2:运行
FROM nginx:alpine

# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制 Nginx 配置
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

frontend/nginx.conf

复制代码
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 80;
        server_name localhost;
        root /usr/share/nginx/html;
        index index.html;

        location / {
            try_files $uri $uri/ /index.html;
        }

        location /api {
            proxy_pass http://backend:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

第五章:配置文件

5.1 MySQL 初始化脚本

mysql/init.sql

复制代码
-- 创建数据库
CREATE DATABASE IF NOT EXISTS blog CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE blog;

-- 创建文章表
CREATE TABLE IF NOT EXISTS articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    author VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入测试数据
INSERT INTO articles (title, content, author) VALUES
('欢迎使用博客系统', '这是我们的第一篇文章!', '管理员'),
('Docker 入门指南', '本文介绍 Docker 的基本概念和使用方法...', '技术编辑'),
('容器化最佳实践', '本文分享容器化部署的最佳实践...', 'DevOps工程师');

5.2 Redis 配置

redis/redis.conf

复制代码
# 基本配置
port 6379
bind 0.0.0.0
protected-mode no

# 持久化配置
save 900 1
save 300 10
save 60 10000

# 内存配置
maxmemory 256mb
maxmemory-policy allkeys-lru

# 日志配置
loglevel notice

5.3 Nginx 配置

nginx/conf.d/blog.conf

复制代码
upstream backend {
    server backend1:3000;
    server backend2:3000;
    server backend3:3000;
    keepalive 32;
}

server {
    listen 80;
    server_name blog.example.com;

    # 前端静态文件
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # API 代理
    location /api {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        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;
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # 健康检查
    location /health {
        access_log off;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}

第六章:开发环境配置

6.1 docker-compose.yml

docker-compose.yml

复制代码
version: '3.8'

services:
  # MySQL 数据库
  mysql:
    image: mysql:5.7
    container_name: blog-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: blog
    volumes:
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - blog-network
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis 缓存
  redis:
    image: redis:7-alpine
    container_name: blog-redis
    command: redis-server /usr/local/etc/redis/redis.conf
    volumes:
      - ./redis/redis.conf:/usr/local/etc/redis/redis.conf
      - redis_data:/data
    ports:
      - "6379:6379"
    networks:
      - blog-network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

  # 后端服务1
  backend1:
    build: ./backend
    container_name: blog-backend-1
    environment:
      NODE_ENV: development
      DB_HOST: mysql
      DB_USER: root
      DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      DB_NAME: blog
      REDIS_HOST: redis
      PORT: 3000
    volumes:
      - ./backend/src:/app/src
    networks:
      - blog-network
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy

  # 后端服务2
  backend2:
    build: ./backend
    container_name: blog-backend-2
    environment:
      NODE_ENV: development
      DB_HOST: mysql
      DB_USER: root
      DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      DB_NAME: blog
      REDIS_HOST: redis
      PORT: 3000
    volumes:
      - ./backend/src:/app/src
    networks:
      - blog-network
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy

  # 前端服务
  frontend:
    image: nginx:alpine
    container_name: blog-frontend
    volumes:
      - ./frontend/public:/usr/share/nginx/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "8080:80"
    networks:
      - blog-network
    depends_on:
      - backend1
      - backend2

networks:
  blog-network:
    driver: bridge

volumes:
  mysql_data:
  redis_data:

6.2 .env 文件

.env

复制代码
# 数据库
MYSQL_ROOT_PASSWORD=your_secure_password_here

# 其他配置
NODE_ENV=development
TZ=Asia/Shanghai

第七章:生产环境配置

7.1 docker-compose.prod.yml

docker-compose.prod.yml

复制代码
version: '3.8'

services:
  mysql:
    image: mysql:5.7
    container_name: blog-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: blog
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "127.0.0.1:3306:3306"
    networks:
      - blog-network
    restart: always
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: blog-redis
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    ports:
      - "127.0.0.1:6379:6379"
    networks:
      - blog-network
    restart: always

  backend:
    image: ${DOCKER_REGISTRY}/blog-backend:${VERSION}
    container_name: blog-backend
    environment:
      NODE_ENV: production
      DB_HOST: mysql
      DB_USER: root
      DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      DB_NAME: blog
      REDIS_HOST: redis
      REDIS_PASSWORD: ${REDIS_PASSWORD}
      PORT: 3000
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    networks:
      - blog-network
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: always

  nginx:
    image: nginx:alpine
    container_name: blog-nginx
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - nginx_logs:/var/log/nginx
    ports:
      - "80:80"
      - "443:443"
    networks:
      - blog-network
    depends_on:
      - backend
    restart: always

networks:
  blog-network:
    driver: bridge

volumes:
  mysql_data:
  redis_data:
  nginx_logs:

7.2 资源限制配置

在生产环境中,我们使用 deploy.resources 进行资源限制:

复制代码
deploy:
  replicas: 3
  resources:
    limits:
      cpus: '0.5'        # 每个容器最多使用 0.5 个 CPU
      memory: 512M      # 每个容器最多使用 512MB 内存
    reservations:
      cpus: '0.25'       # 预留资源
      memory: 256M

第八章:监控与日志

8.1 Prometheus 配置

monitoring/prometheus.yml

复制代码
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'blog-backend'
    static_configs:
      - targets: ['backend:3000']
        labels:
          app: 'blog-api'

  - job_name: 'nginx'
    static_configs:
      - targets: ['nginx:80']

8.2 日志管理

配置日志轮转:

复制代码
services:
  backend:
    image: ${DOCKER_REGISTRY}/blog-backend:${VERSION}
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

第九章:部署流程

9.1 开发环境启动

复制代码
# 1. 克隆代码
git clone https://github.com/yourusername/blog-app.git
cd blog-app

# 2. 创建 .env 文件
cp .env.example .env
# 编辑 .env 文件,设置密码

# 3. 启动开发环境
docker-compose up -d

# 4. 查看服务状态
docker-compose ps

# 5. 查看日志
docker-compose logs -f

# 6. 访问应用
# 前端: http://localhost:8080
# API: http://localhost:8080/api/articles

9.2 生产环境部署

复制代码
# 1. 构建镜像
docker-compose -f docker-compose.prod.yml build

# 2. 标记镜像版本
docker tag blog-backend:latest ${DOCKER_REGISTRY}/blog-backend:${VERSION}
docker tag blog-backend:latest ${DOCKER_REGISTRY}/blog-backend:latest

# 3. 推送镜像
docker push ${DOCKER_REGISTRY}/blog-backend:${VERSION}
docker push ${DOCKER_REGISTRY}/blog-backend:latest

# 4. 部署到服务器
ssh user@server
cd /opt/blog-app
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d

# 5. 查看服务状态
docker-compose -f docker-compose.prod.yml ps
docker-compose -f docker-compose.prod.yml logs -f

9.3 更新与回滚

复制代码
# 更新服务
docker-compose -f docker-compose.prod.yml up -d --no-deps backend

# 回滚到上一版本
docker-compose -f docker-compose.prod.yml rollback backend

# 查看更新历史
docker-compose -f docker-compose.prod.yml ps

第十章:性能优化

10.1 网络优化

  • 使用 keepalive 连接池

  • 配置合理的缓冲区大小

  • 启用压缩(gzip)

    Nginx 配置

    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    gzip_min_length 1000;

10.2 存储优化

复制代码
services:
  mysql:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password --innodb-buffer-pool-size=256M

10.3 缓存优化

  • 合理设置 Redis 缓存时间

  • 使用缓存预热

  • 监控缓存命中率

    查看 Redis 统计信息

    docker exec blog-redis redis-cli info stats


本周总结

本周我们完成了一个完整的实战项目:

  1. 项目架构设计:前端 + 后端 + 数据库 + 缓存
  2. 多服务开发:Node.js API + Vue.js 前端
  3. 配置文件:MySQL、Redis、Nginx
  4. 环境配置:开发环境和生产环境
  5. 资源限制:CPU、内存限制
  6. 监控日志:日志轮转、健康检查
  7. 部署流程:构建、推送、部署
  8. 性能优化:网络、存储、缓存优化

练习作业

  1. 完成整个项目的部署
  2. 配置健康检查和监控
  3. 实现蓝绿部署
相关推荐
Inhand陈工2 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn862 小时前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智3 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_3 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉4 小时前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦4 小时前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
2601_961875245 小时前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant
java_cj5 小时前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
lsyeei5 小时前
linux 系统目录详解
linux·运维·服务器
程序员老赵5 小时前
服务器没有桌面?Docker 跑个 Chrome,浏览器就能远程用
docker·容器·devops