05:Docker练习项目

05. Docker 练习项目

5.1 项目 1:全栈 Web 应用(MERN Stack)

5.1.1 项目概述

技术栈:

  • MongoDB - 数据库
  • Express - 后端框架
  • React - 前端框架
  • Node.js - 运行时环境

项目结构:

复制代码
mern-app/
├── docker-compose.yml
├── .env
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   ├── server.js
│   └── src/
├── frontend/
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── package.json
│   └── src/
└── nginx/
    └── nginx.conf

5.1.2 后端 Dockerfile

backend/Dockerfile:

dockerfile 复制代码
FROM node:18-alpine

WORKDIR /app

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

# 安装依赖
RUN npm ci --only=production

# 复制源代码
COPY . .

# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001 && \
    chown -R nodejs:nodejs /app

USER nodejs

EXPOSE 5000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
  CMD node -e "require('http').get('http://localhost:5000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

CMD ["node", "server.js"]

backend/server.js(示例):

javascript 复制代码
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');

const app = express();

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

// MongoDB 连接
mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
})
.then(() => console.log('MongoDB connected'))
.catch(err => console.error('MongoDB connection error:', err));

// 路由
app.get('/api/health', (req, res) => {
  res.json({ status: 'OK' });
});

app.get('/api/items', async (req, res) => {
  // 业务逻辑
  res.json({ items: [] });
});

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

5.1.3 前端 Dockerfile

frontend/Dockerfile(开发环境):

dockerfile 复制代码
FROM node:18-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

frontend/Dockerfile.prod(生产环境 - 多阶段构建):

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

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine

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

# 复制 NGINX 配置
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

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

5.1.4 Docker Compose 配置

docker-compose.yml:

yaml 复制代码
version: '3.8'

services:
  # MongoDB 数据库
  mongodb:
    image: mongo:6
    container_name: mern-mongodb
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USER}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}
      MONGO_INITDB_DATABASE: ${MONGO_DB}
    volumes:
      - mongodb-data:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
    ports:
      - "27017:27017"
    networks:
      - mern-network
    restart: unless-stopped
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet
      interval: 10s
      timeout: 5s
      retries: 5

  # 后端 API
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    container_name: mern-backend
    environment:
      NODE_ENV: ${NODE_ENV}
      PORT: 5000
      MONGO_URI: mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@mongodb:27017/${MONGO_DB}?authSource=admin
      JWT_SECRET: ${JWT_SECRET}
    ports:
      - "5000:5000"
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      mongodb:
        condition: service_healthy
    networks:
      - mern-network
    restart: unless-stopped

  # 前端应用
  frontend:
    build:
      context: ./frontend
      dockerfile: ${FRONTEND_DOCKERFILE:-Dockerfile}
    container_name: mern-frontend
    environment:
      REACT_APP_API_URL: ${REACT_APP_API_URL}
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - backend
    networks:
      - mern-network
    restart: unless-stopped
    stdin_open: true
    tty: true

volumes:
  mongodb-data:

networks:
  mern-network:
    driver: bridge

.env 文件:

env 复制代码
# 环境
NODE_ENV=development

# MongoDB
MONGO_ROOT_USER=admin
MONGO_ROOT_PASSWORD=secret123
MONGO_DB=mernapp

# JWT
JWT_SECRET=your-secret-key

# 前端
REACT_APP_API_URL=http://localhost:5000/api
FRONTEND_DOCKERFILE=Dockerfile

5.1.5 NGINX 反向代理(生产环境)

nginx/nginx.conf:

nginx 复制代码
server {
    listen 80;
    server_name localhost;

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

    # 代理后端 API
    location /api {
        proxy_pass http://backend:5000;
        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;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

5.1.6 启动和使用

bash 复制代码
# 开发环境
docker compose up -d

# 生产环境
NODE_ENV=production FRONTEND_DOCKERFILE=Dockerfile.prod docker compose up -d --build

# 查看日志
docker compose logs -f

# 进入 MongoDB
docker exec -it mern-mongodb mongosh -u admin -p secret123

# 停止服务
docker compose down

# 停止并删除数据
docker compose down -v

5.2 项目 2:电商平台微服务

5.2.1 架构设计

复制代码
                    ┌─────────────┐
                    │   NGINX     │
                    │  (Gateway)  │
                    └──────┬──────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
   ┌────▼────┐       ┌─────▼─────┐     ┌─────▼─────┐
   │ User    │       │ Product   │     │ Order     │
   │ Service │       │ Service   │     │ Service   │
   └────┬────┘       └─────┬─────┘     └─────┬─────┘
        │                  │                  │
        └──────────────────┼──────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        │                  │                  │
   ┌────▼────┐       ┌─────▼─────┐     ┌─────▼─────┐
   │PostgreSQL│       │   Redis   │     │ RabbitMQ  │
   └─────────┘       └───────────┘     └───────────┘

5.2.2 Docker Compose 配置

docker-compose.yml:

yaml 复制代码
version: '3.8'

services:
  # =============================================================================
  # 基础设施服务
  # =============================================================================

  # PostgreSQL 数据库
  postgres:
    image: postgres:15-alpine
    container_name: ecommerce-postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: ecommerce
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis 缓存
  redis:
    image: redis:7-alpine
    container_name: ecommerce-redis
    command: redis-server --appendonly yes --requirepass redis123
    volumes:
      - redis-data:/data
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # RabbitMQ 消息队列
  rabbitmq:
    image: rabbitmq:3-management-alpine
    container_name: ecommerce-rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: admin123
    ports:
      - "15672:15672"  # 管理界面
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: rabbitmq-diagnostics -q ping
      interval: 10s
      timeout: 5s
      retries: 5

  # =============================================================================
  # 微服务
  # =============================================================================

  # 用户服务
  user-service:
    build:
      context: ./services/user
      dockerfile: Dockerfile
    container_name: user-service
    environment:
      SERVICE_NAME: user-service
      PORT: 3001
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/ecommerce
      REDIS_URL: redis://:redis123@redis:6379
      JWT_SECRET: ${JWT_SECRET}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 产品服务
  product-service:
    build:
      context: ./services/product
      dockerfile: Dockerfile
    container_name: product-service
    environment:
      SERVICE_NAME: product-service
      PORT: 3002
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/ecommerce
      REDIS_URL: redis://:redis123@redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3002/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # 订单服务
  order-service:
    build:
      context: ./services/order
      dockerfile: Dockerfile
    container_name: order-service
    environment:
      SERVICE_NAME: order-service
      PORT: 3003
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/ecommerce
      REDIS_URL: redis://:redis123@redis:6379
      RABBITMQ_URL: amqp://admin:admin123@rabbitmq:5672
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      rabbitmq:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3003/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # =============================================================================
  # API 网关
  # =============================================================================

  nginx:
    image: nginx:alpine
    container_name: ecommerce-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
    depends_on:
      - user-service
      - product-service
      - order-service
    networks:
      - frontend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
      interval: 10s
      timeout: 5s
      retries: 3

  # =============================================================================
  # 监控和管理工具(可选)
  # =============================================================================

  # Adminer - 数据库管理
  adminer:
    image: adminer:latest
    container_name: ecommerce-adminer
    ports:
      - "8080:8080"
    networks:
      - backend
    restart: unless-stopped
    profiles:
      - tools

volumes:
  postgres-data:
  redis-data:
  rabbitmq-data:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

5.2.3 NGINX 网关配置

nginx/nginx.conf:

nginx 复制代码
events {
    worker_connections 1024;
}

http {
    upstream user_service {
        server user-service:3001;
    }

    upstream product_service {
        server product-service:3002;
    }

    upstream order_service {
        server order-service:3003;
    }

    server {
        listen 80;
        server_name localhost;

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

        # 用户服务
        location /api/users {
            proxy_pass http://user_service;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 产品服务
        location /api/products {
            proxy_pass http://product_service;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 订单服务
        location /api/orders {
            proxy_pass http://order_service;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

5.2.4 微服务 Dockerfile 示例

services/user/Dockerfile:

dockerfile 复制代码
FROM node:18-alpine

WORKDIR /app

# 安装依赖
COPY package*.json ./
RUN npm ci --only=production

# 复制源代码
COPY . .

# 非 root 用户
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

EXPOSE 3001

HEALTHCHECK --interval=30s --timeout=3s \
  CMD node -e "require('http').get('http://localhost:3001/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

CMD ["node", "index.js"]

5.3 项目 3:DevOps 工具链

5.3.1 完整的 CI/CD 环境

docker-compose.yml:

yaml 复制代码
version: '3.8'

services:
  # GitLab CE
  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: devops-gitlab
    hostname: gitlab.local
    ports:
      - "8929:80"
      - "2289:22"
    volumes:
      - gitlab-config:/etc/gitlab
      - gitlab-logs:/var/log/gitlab
      - gitlab-data:/var/opt/gitlab
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.local:8929'
        gitlab_rails['gitlab_shell_ssh_port'] = 2289
    networks:
      - devops
    restart: unless-stopped
    shm_size: '256m'

  # Jenkins
  jenkins:
    image: jenkins/jenkins:lts
    container_name: devops-jenkins
    user: root
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - jenkins-data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      JAVA_OPTS: "-Djenkins.install.runSetupWizard=false"
    networks:
      - devops
    restart: unless-stopped

  # SonarQube - 代码质量检查
  sonarqube:
    image: sonarqube:community
    container_name: devops-sonarqube
    ports:
      - "9000:9000"
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://postgres:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    volumes:
      - sonarqube-data:/opt/sonarqube/data
      - sonarqube-extensions:/opt/sonarqube/extensions
      - sonarqube-logs:/opt/sonarqube/logs
    depends_on:
      - postgres
    networks:
      - devops
    restart: unless-stopped

  # Nexus - 制品库
  nexus:
    image: sonatype/nexus3:latest
    container_name: devops-nexus
    ports:
      - "8081:8081"
      - "8082:8082"  # Docker Registry
    volumes:
      - nexus-data:/nexus-data
    networks:
      - devops
    restart: unless-stopped

  # PostgreSQL(SonarQube 数据库)
  postgres:
    image: postgres:15-alpine
    container_name: devops-postgres
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
      POSTGRES_DB: sonar
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - devops
    restart: unless-stopped

  # Harbor - Docker Registry
  harbor:
    image: goharbor/harbor:v2.8.0
    container_name: devops-harbor
    ports:
      - "8090:80"
    volumes:
      - harbor-data:/data
    networks:
      - devops
    restart: unless-stopped

volumes:
  gitlab-config:
  gitlab-logs:
  gitlab-data:
  jenkins-data:
  sonarqube-data:
  sonarqube-extensions:
  sonarqube-logs:
  nexus-data:
  postgres-data:
  harbor-data:

networks:
  devops:
    driver: bridge

5.4 项目 4:监控和日志系统

5.4.1 ELK + Prometheus + Grafana

docker-compose.yml:

yaml 复制代码
version: '3.8'

services:
  # =============================================================================
  # ELK Stack(日志收集)
  # =============================================================================

  # Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.10.0
    container_name: monitoring-elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch-data:/usr/share/elasticsearch/data
    networks:
      - monitoring
    restart: unless-stopped

  # Kibana
  kibana:
    image: docker.elastic.co/kibana/kibana:8.10.0
    container_name: monitoring-kibana
    ports:
      - "5601:5601"
    environment:
      ELASTICSEARCH_HOSTS: http://elasticsearch:9200
    depends_on:
      - elasticsearch
    networks:
      - monitoring
    restart: unless-stopped

  # Logstash
  logstash:
    image: docker.elastic.co/logstash/logstash:8.10.0
    container_name: monitoring-logstash
    ports:
      - "5000:5000"
      - "9600:9600"
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
    environment:
      LS_JAVA_OPTS: "-Xms256m -Xmx256m"
    depends_on:
      - elasticsearch
    networks:
      - monitoring
    restart: unless-stopped

  # Filebeat(日志采集器)
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.10.0
    container_name: monitoring-filebeat
    user: root
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    depends_on:
      - elasticsearch
      - logstash
    networks:
      - monitoring
    restart: unless-stopped

  # =============================================================================
  # Prometheus + Grafana(监控)
  # =============================================================================

  # Prometheus
  prometheus:
    image: prom/prometheus:latest
    container_name: monitoring-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - monitoring
    restart: unless-stopped

  # Grafana
  grafana:
    image: grafana/grafana:latest
    container_name: monitoring-grafana
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: admin123
      GF_INSTALL_PLUGINS: grafana-piechart-panel
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    depends_on:
      - prometheus
    networks:
      - monitoring
    restart: unless-stopped

  # Node Exporter(主机监控)
  node-exporter:
    image: prom/node-exporter:latest
    container_name: monitoring-node-exporter
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    networks:
      - monitoring
    restart: unless-stopped

  # cAdvisor(容器监控)
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: monitoring-cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    networks:
      - monitoring
    restart: unless-stopped

  # AlertManager(告警)
  alertmanager:
    image: prom/alertmanager:latest
    container_name: monitoring-alertmanager
    ports:
      - "9093:9093"
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
      - alertmanager-data:/alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    networks:
      - monitoring
    restart: unless-stopped

volumes:
  elasticsearch-data:
  prometheus-data:
  grafana-data:
  alertmanager-data:

networks:
  monitoring:
    driver: bridge

5.4.2 Prometheus 配置

prometheus/prometheus.yml:

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

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

scrape_configs:
  # Prometheus 自身
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Node Exporter
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

  # cAdvisor
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

  # 你的应用
  - job_name: 'my-app'
    static_configs:
      - targets: ['app:3000']

5.5 项目 5:大数据处理平台

docker-compose.yml:

yaml 复制代码
version: '3.8'

services:
  # Hadoop NameNode
  namenode:
    image: bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8
    container_name: bigdata-namenode
    ports:
      - "9870:9870"
      - "9000:9000"
    volumes:
      - hadoop-namenode:/hadoop/dfs/name
    environment:
      CLUSTER_NAME: bigdata
    networks:
      - bigdata
    restart: unless-stopped

  # Hadoop DataNode
  datanode:
    image: bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8
    container_name: bigdata-datanode
    volumes:
      - hadoop-datanode:/hadoop/dfs/data
    environment:
      SERVICE_PRECONDITION: "namenode:9870"
    depends_on:
      - namenode
    networks:
      - bigdata
    restart: unless-stopped

  # Spark Master
  spark-master:
    image: bde2020/spark-master:3.1.1-hadoop3.2
    container_name: bigdata-spark-master
    ports:
      - "8081:8080"
      - "7077:7077"
    environment:
      INIT_DAEMON_STEP: setup_spark
    networks:
      - bigdata
    restart: unless-stopped

  # Spark Worker
  spark-worker:
    image: bde2020/spark-worker:3.1.1-hadoop3.2
    container_name: bigdata-spark-worker
    depends_on:
      - spark-master
    environment:
      SPARK_MASTER: spark://spark-master:7077
    networks:
      - bigdata
    restart: unless-stopped

  # Kafka
  kafka:
    image: wurstmeister/kafka:latest
    container_name: bigdata-kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: kafka
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_CREATE_TOPICS: "test:1:1"
    depends_on:
      - zookeeper
    networks:
      - bigdata
    restart: unless-stopped

  # Zookeeper
  zookeeper:
    image: wurstmeister/zookeeper:latest
    container_name: bigdata-zookeeper
    ports:
      - "2181:2181"
    networks:
      - bigdata
    restart: unless-stopped

volumes:
  hadoop-namenode:
  hadoop-datanode:

networks:
  bigdata:
    driver: bridge

5.6 常用管理脚本

5.6.1 项目启动脚本

start.sh

bash 复制代码
#!/bin/bash

echo "🚀 启动 Docker 服务..."

# 检查 Docker 是否运行
if ! docker info > /dev/null 2>&1; then
    echo "❌ Docker 未运行,请先启动 Docker"
    exit 1
fi

# 拉取最新镜像
echo "📦 拉取最新镜像..."
docker compose pull

# 构建自定义镜像
echo "🔨 构建镜像..."
docker compose build

# 启动服务
echo "▶️  启动服务..."
docker compose up -d

# 等待服务就绪
echo "⏳ 等待服务启动..."
sleep 10

# 检查服务状态
echo "📊 服务状态:"
docker compose ps

echo "✅ 所有服务已启动!"

5.6.2 备份脚本

backup.sh

bash 复制代码
#!/bin/bash

BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

echo "🔄 开始备份..."

# 备份数据库
docker compose exec -T db pg_dump -U postgres mydb > "$BACKUP_DIR/db_$DATE.sql"

# 备份数据卷
docker run --rm \
  -v myproject_data:/source:ro \
  -v $(pwd)/$BACKUP_DIR:/backup \
  ubuntu \
  tar czf /backup/volumes_$DATE.tar.gz -C /source .

echo "✅ 备份完成: $BACKUP_DIR"
相关推荐
oMcLin2 小时前
Ubuntu 22.04 Docker 容器启动失败:解决 Overlay2 存储驱动冲突
java·ubuntu·docker
幺零九零零2 小时前
Windows + Docker + k6 + InfluxDB + Grafana
windows·docker·grafana
qq_317620313 小时前
01:Docker 概述
运维·docker·容器·docker安装
qq_317620314 小时前
04:Docker-Compose完全指南
docker·容器编排·服务配置·依赖管理·多环境部署
我可以将你更新哟4 小时前
【docker】Dockerfile的编写
docker·容器
❀͜͡傀儡师4 小时前
docker部署orion-ops一站式智能运维管理平台
运维·docker·容器·orion-ops
DarkAthena6 小时前
【DOCKER+ORACLE】使用docker-compose一键拉起一个ORACLE-ADG一主一备环境
docker·oracle·容器
❀͜͡傀儡师6 小时前
docker部署Portracker 实现局域网实时端口监控
docker·容器·portracker
我可以将你更新哟6 小时前
【docker测试】在Ubuntu 22.04.3中部署docker
ubuntu·adb·docker