Bareos容器化部署深度指南

作为CTO,我将为您详细解析Bareos的容器化部署方案,这是现代备份系统的趋势,能大幅提升部署灵活性和可维护性。

一、容器化架构设计

1.1 架构对比:传统 vs 容器化

传统部署:
┌─────────────────────────────────────────┐
│ 物理服务器/虚拟机                       │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐ │
│  │PostgreSQL│  │ Director│  │ Storage │ │
│  └─────────┘  └─────────┘  └─────────┘ │
│  ┌─────────┐  ┌─────────┐               │
│  │  WebUI  │  │   NFS   │               │
│  └─────────┘  └─────────┘               │
└─────────────────────────────────────────┘

容器化部署:
┌─────────────────────────────────────────┐
│ Docker Host / Kubernetes Cluster        │
│  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐       │
│  │ DB  │ │ Dir │ │ SD  │ │WebUI│       │
│  │     │ │     │ │     │ │     │       │
│  └─────┘ └─────┘ └─────┘ └─────┘       │
│  ┌─────────────────────────────┐       │
│  │       Shared Volumes        │       │
│  └─────────────────────────────┘       │
└─────────────────────────────────────────┘

1.2 容器化优势

  • 快速部署:几分钟内完成整个备份系统部署
  • 环境一致:消除"在我机器上能运行"的问题
  • 资源隔离:每个组件独立运行,互不干扰
  • 易于扩展:水平扩展存储守护进程
  • 简化升级:滚动更新,零停机升级

二、完整Docker Compose方案

2.1 基础部署结构

# 项目目录结构
bareos-docker/
├── docker-compose.yml          # 主部署文件
├── .env                        # 环境变量
├── config/                     # 配置文件
│   ├── bareos-dir/            # Director配置
│   ├── bareos-sd/             # Storage配置
│   ├── bareos-fd/             # File Daemon模板
│   └── webui/                 # Web界面配置
├── scripts/                    # 工具脚本
├── storage/                    # 备份数据存储
└── logs/                      # 日志目录

2.2 详细docker-compose.yml

version: '3.8'

# 网络配置
networks:
  bareos-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24
    # 启用MACVLAN用于客户端通信(可选)
    # driver: macvlan
    # driver_opts:
    #   parent: eth0
    # ipam:
    #   config:
    #     - subnet: 192.168.1.0/24
    #       gateway: 192.168.1.1

# 卷定义
volumes:
  postgres_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./data/postgres
  bareos_storage:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./storage
  bareos_config:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./config
  bareos_logs:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./logs

# 服务定义
services:
  # 1. PostgreSQL数据库
  bareos-db:
    image: postgres:15-alpine
    container_name: bareos-postgres
    restart: unless-stopped
    networks:
      bareos-net:
        ipv4_address: 172.20.0.10
    environment:
      POSTGRES_DB: bareos
      POSTGRES_USER: ${DB_USER:-bareos}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-ChangeThisPassword!}
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-bareos}"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    mem_limit: 1g
    cpus: 0.5
    deploy:
      resources:
        limits:
          memory: 1G
        reservations:
          memory: 512M

  # 2. Bareos Director
  bareos-director:
    image: bareos/bareos-director:23.0
    container_name: bareos-director
    restart: unless-stopped
    depends_on:
      bareos-db:
        condition: service_healthy
    networks:
      bareos-net:
        ipv4_address: 172.20.0.20
    ports:
      - "9101:9101"  # Director端口
      - "9102:9102"  # 客户端连接端口(可选暴露)
    environment:
      DB_HOST: bareos-db
      DB_PORT: 5432
      DB_NAME: bareos
      DB_USER: ${DB_USER:-bareos}
      DB_PASSWORD: ${DB_PASSWORD:-ChangeThisPassword!}
      TIMEZONE: ${TIMEZONE:-Asia/Shanghai}
      BAREOS_DIR_HOSTNAME: bareos-director
      BAREOS_DIR_PORT: 9101
      BAREOS_SD_HOSTNAME: bareos-storage
      BAREOS_SD_PORT: 9103
    volumes:
      - bareos_config/bareos-dir:/etc/bareos/bareos-dir.d:rw
      - bareos_logs:/var/log/bareos:rw
      - ./scripts/init-director.sh:/docker-entrypoint-init.d/init.sh
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    healthcheck:
      test: ["CMD", "bash", "-c", "echo status director | bconsole | grep -q 'bareos-dir'"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    mem_limit: 2g
    cpus: 1
    extra_hosts:
      - "host.docker.internal:host-gateway"

  # 3. Bareos Storage Daemon
  bareos-storage:
    image: bareos/bareos-storage:23.0
    container_name: bareos-storage
    restart: unless-stopped
    depends_on:
      - bareos-director
    networks:
      bareos-net:
        ipv4_address: 172.20.0.30
    ports:
      - "9103:9103"  # Storage Daemon端口
    environment:
      BAREOS_SD_HOSTNAME: bareos-storage
      BAREOS_SD_PORT: 9103
      BAREOS_DIR_HOSTNAME: bareos-director
      BAREOS_DIR_PORT: 9101
      TIMEZONE: ${TIMEZONE:-Asia/Shanghai}
      STORAGE_DEVICES: "FileStorage, S3Storage"
    volumes:
      - bareos_config/bareos-sd:/etc/bareos/bareos-sd.d:rw
      - bareos_storage:/bareos/storage:rw
      - bareos_logs:/var/log/bareos:rw
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      # 挂载本地目录作为备份目标
      - /data/backup:/data/backup:rw
      - /mnt/nas/backup:/mnt/nas/backup:rw
    devices:
      - "/dev/fuse"  # 用于S3/FUSE挂载
    privileged: true  # 需要挂载权限
    cap_add:
      - SYS_ADMIN
      - SYS_RAWIO
    healthcheck:
      test: ["CMD", "bash", "-c", "echo status storage | bconsole | grep -q 'bareos-sd'"]
      interval: 30s
      timeout: 10s
      retries: 3
    mem_limit: 2g
    cpus: 1
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

  # 4. Bareos WebUI
  bareos-webui:
    image: bareos/bareos-webui:23.0
    container_name: bareos-webui
    restart: unless-stopped
    depends_on:
      - bareos-director
    networks:
      bareos-net:
        ipv4_address: 172.20.0.40
    ports:
      - "80:80"     # HTTP
      - "443:443"   # HTTPS(如果配置TLS)
    environment:
      BAREOS_DIR_HOST: bareos-director
      BAREOS_DIR_PORT: 9101
      WEBUI_HOSTNAME: bareos-webui
      WEBUI_PORT: 80
      TIMEZONE: ${TIMEZONE:-Asia/Shanghai}
      # Apache配置
      APACHE_SERVER_NAME: backup.company.com
      APACHE_SERVER_ADMIN: admin@company.com
      # TLS配置(可选)
      # TLS_CERT_FILE: /etc/ssl/certs/webui.crt
      # TLS_KEY_FILE: /etc/ssl/private/webui.key
    volumes:
      - bareos_config/webui:/etc/bareos-webui:rw
      - ./certs:/etc/ssl:ro  # TLS证书
      - bareos_logs:/var/log/bareos:rw
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
    mem_limit: 512m
    cpus: 0.5

  # 5. Prometheus监控(可选)
  prometheus:
    image: prom/prometheus:v2.45.0
    container_name: bareos-prometheus
    restart: unless-stopped
    networks:
      bareos-net:
        ipv4_address: 172.20.0.50
    ports:
      - "9090:9090"
    volumes:
      - ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/console_templates'
      - '--storage.tsdb.retention.time=90d'
      - '--web.enable-lifecycle'
    mem_limit: 1g

  # 6. Grafana仪表板(可选)
  grafana:
    image: grafana/grafana:10.0.0
    container_name: bareos-grafana
    restart: unless-stopped
    depends_on:
      - prometheus
    networks:
      bareos-net:
        ipv4_address: 172.20.0.60
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-ChangeThisPassword!}
      GF_INSTALL_PLUGINS: "grafana-piechart-panel"
    volumes:
      - grafana_data:/var/lib/grafana
      - ./config/grafana/dashboards:/etc/grafana/provisioning/dashboards
      - ./config/grafana/datasources:/etc/grafana/provisioning/datasources
    mem_limit: 512m

  # 7. Traefik反向代理(生产环境推荐)
  traefik:
    image: traefik:v3.0
    container_name: traefik
    restart: unless-stopped
    networks:
      bareos-net:
        ipv4_address: 172.20.0.70
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"  # 管理界面
    command:
      - --api.dashboard=true
      - --api.insecure=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.le.acme.tlschallenge=true
      - --certificatesresolvers.le.acme.email=admin@company.com
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    labels:
      - "traefik.enable=true"
      # WebUI路由
      - "traefik.http.routers.bareos-webui.rule=Host(`backup.company.com`)"
      - "traefik.http.routers.bareos-webui.entrypoints=websecure"
      - "traefik.http.routers.bareos-webui.tls.certresolver=le"
      - "traefik.http.services.bareos-webui.loadbalancer.server.port=80"

2.3 环境变量文件 (.env)

# Bareos Docker环境配置
# ========================

# 数据库配置
DB_USER=bareos
DB_PASSWORD=StrongPassword123!
DB_ROOT_PASSWORD=RootPassword456!

# 时区配置
TIMEZONE=Asia/Shanghai

# 网络配置
DOCKER_SUBNET=172.20.0.0/24
DOCKER_GATEWAY=172.20.0.1

# Bareos组件配置
BAREOS_DIR_PASSWORD=DirectorPassword789!
BAREOS_SD_PASSWORD=StoragePassword101!
BAREOS_MON_PASSWORD=MonitorPassword112!

# WebUI配置
WEBUI_USERNAME=admin
WEBUI_PASSWORD=WebUIPassword131!

# 监控配置
GRAFANA_PASSWORD=GrafanaPassword415!

# S3存储配置(如果使用)
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
S3_BUCKET_NAME=your-bucket-name
S3_ENDPOINT_URL=https://s3.amazonaws.com
S3_REGION=us-east-1

# 邮件通知配置
SMTP_HOST=smtp.company.com
SMTP_PORT=587
SMTP_USER=backup@company.com
SMTP_PASSWORD=EmailPassword161!
ALERT_EMAILS=admin@company.com,cto@company.com

# 存储路径
DATA_DIR=./data
CONFIG_DIR=./config
STORAGE_DIR=./storage
LOG_DIR=./logs

# 性能调优
POSTGRES_SHARED_BUFFERS=256MB
POSTGRES_EFFECTIVE_CACHE_SIZE=1GB
BAREOS_MAX_JOBS=20
BAREOS_MAX_CONNECTIONS=50

三、配置文件详解

3.1 Director配置模板

# config/bareos-dir/director/bareos-dir.conf
Director {
  Name = bareos-dir
  DirAddress = 0.0.0.0
  DirPort = 9101
  QueryFile = "/usr/lib/bareos/scripts/query.sql"
  WorkingDirectory = "/var/lib/bareos"
  PidDirectory = "/run/bareos"
  Maximum Concurrent Jobs = ${BAREOS_MAX_JOBS:-20}
  Password = "${BAREOS_DIR_PASSWORD}"

  # 数据库连接
  @/etc/bareos/bareos-dir.d/catalog/postgresql.conf

  # 消息处理
  Messages = Daemon

  # TLS配置
  TLS Enable = yes
  TLS Require = yes
  TLS Certificate = "/etc/bareos/tls/cert.pem"
  TLS Key = "/etc/bareos/tls/key.pem"
  TLS Verify Peer = no
  TLS Allowed CN = "bareos-director"

  # 审计日志
  Audit Events = JobStart, JobEnd, VolumeFull
}

# 数据库配置
# config/bareos-dir/catalog/postgresql.conf
Catalog {
  Name = PostgreSQL
  dbdriver = "postgresql"
  dbaddress = "${DB_HOST}"
  dbport = "${DB_PORT}"
  dbname = "${DB_NAME}"
  dbuser = "${DB_USER}"
  dbpassword = "${DB_PASSWORD}"
}

3.2 Storage配置模板

# config/bareos-sd/storage/bareos-sd.conf
Storage {
  Name = bareos-sd
  SDPort = 9103
  WorkingDirectory = "/var/lib/bareos"
  PidDirectory = "/run/bareos"
  Maximum Concurrent Jobs = 15
  Messages = Daemon
  SDAddress = 0.0.0.0

  # Director访问权限
  @/etc/bareos/bareos-sd.d/director/bareos-dir.conf
}

# Director访问配置
# config/bareos-sd/director/bareos-dir.conf
Director {
  Name = bareos-dir
  Password = "${BAREOS_DIR_PASSWORD}"
}

# 文件存储设备
# config/bareos-sd/device/FileStorage.conf
Device {
  Name = FileStorage
  Media Type = File
  Archive Device = /bareos/storage
  LabelMedia = yes
  Random Access = yes
  AutomaticMount = yes
  RemovableMedia = no
  AlwaysOpen = no
  Maximum Concurrent Jobs = 5

  # 存储池配置
  Device Type = File
  Media Type = File

  # 挂载选项(如果使用外部存储)
  Mount Command = "/bin/mount"
  Unmount Command = "/bin/umount"
}

3.3 客户端配置模板

# config/bareos-dir/client/linux-server.conf
Client {
  Name = linux-server-fd
  Address = 192.168.1.100  # 客户端实际IP
  FDPort = 9102
  Catalog = PostgreSQL
  Password = "client_secret_password_linux"
  File Retention = 30 days
  Job Retention = 12 months
  AutoPrune = yes
}

# Windows客户端配置
# config/bareos-dir/client/windows-server.conf
Client {
  Name = windows-server-fd
  Address = 192.168.1.101
  FDPort = 9102
  Catalog = PostgreSQL
  Password = "client_secret_password_windows"
  File Retention = 30 days
  Job Retention = 12 months
  AutoPrune = yes
}

3.4 WebUI配置

# config/webui/apache.conf
<VirtualHost *:80>
    ServerName backup.company.com
    ServerAdmin admin@company.com

    DocumentRoot /var/www/html/bareos-webui

    <Directory /var/www/html/bareos-webui>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted

        # 安全限制
        <IfModule mod_headers.c>
            Header set X-Content-Type-Options "nosniff"
            Header set X-Frame-Options "SAMEORIGIN"
            Header set X-XSS-Protection "1; mode=block"
        </IfModule>
    </Directory>

    # PHP配置
    <FilesMatch \.php$>
        SetHandler "proxy:fcgi://php-fpm:9000"
    </FilesMatch>

    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined

    # 重定向到HTTPS(如果启用TLS)
    # Redirect permanent / https://backup.company.com/
</VirtualHost>

# HTTPS配置(可选)
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName backup.company.com

    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/webui.crt
    SSLCertificateKeyFile /etc/ssl/private/webui.key

    # HSTS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    # 其他配置同上
</VirtualHost>
</IfModule>

四、初始化脚本

4.1 数据库初始化脚本

#!/bin/bash
# scripts/init-db.sql
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- 创建额外监控用户
CREATE USER bareos_mon WITH PASSWORD '${BAREOS_MON_PASSWORD}';
GRANT CONNECT ON DATABASE bareos TO bareos_mon;
GRANT USAGE ON SCHEMA public TO bareos_mon;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO bareos_mon;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO bareos_mon;

-- 创建备份用户(用于逻辑备份)
CREATE USER bareos_backup WITH PASSWORD 'BackupUserPassword';
GRANT CONNECT ON DATABASE bareos TO bareos_backup;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO bareos_backup;

-- 创建性能监控表
CREATE TABLE IF NOT EXISTS bareos_metrics (
    id SERIAL PRIMARY KEY,
    metric_name VARCHAR(100) NOT NULL,
    metric_value DOUBLE PRECISION,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    labels JSONB
);

CREATE INDEX idx_bareos_metrics_timestamp ON bareos_metrics(timestamp);
CREATE INDEX idx_bareos_metrics_name ON bareos_metrics(metric_name);

4.2 Director初始化脚本

#!/bin/bash
# scripts/init-director.sh
set -e

echo "Initializing Bareos Director..."

# 等待数据库就绪
until PGPASSWORD=${DB_PASSWORD} psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -c '\q'; do
  echo "Waiting for database..."
  sleep 5
done

# 检查数据库是否已初始化
if ! PGPASSWORD=${DB_PASSWORD} psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -c "SELECT * FROM Job LIMIT 1;" &>/dev/null; then
    echo "Initializing Bareos database..."

    # 运行Bareos初始化脚本
    /usr/lib/bareos/scripts/create_bareos_database
    /usr/lib/bareos/scripts/make_bareos_tables
    /usr/lib/bareos/scripts/grant_bareos_privileges

    # 创建基础配置
    create_base_configs

    echo "Database initialized successfully."
else
    echo "Database already initialized."
fi

# 设置目录权限
chown -R bareos:bareos /etc/bareos
chown -R bareos:bareos /var/log/bareos
chmod -R 750 /etc/bareos

# 生成TLS证书(如果不存在)
if [ ! -f /etc/bareos/tls/cert.pem ]; then
    echo "Generating TLS certificates..."
    mkdir -p /etc/bareos/tls
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
        -keyout /etc/bareos/tls/key.pem \
        -out /etc/bareos/tls/cert.pem \
        -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=bareos-director"
    chown -R bareos:bareos /etc/bareos/tls
    chmod 600 /etc/bareos/tls/*
fi

echo "Director initialization complete."

# 启动Director
exec "$@"

# 辅助函数
create_base_configs() {
    # 创建基本作业配置
    cat > /etc/bareos/bareos-dir.d/job/DefaultBackup.conf << EOF
JobDefs {
  Name = "DefaultBackup"
  Type = Backup
  Level = Incremental
  Messages = Standard
  Priority = 10
  Write Bootstrap = "/var/lib/bareos/%c.bsr"
  Full Backup Pool = Full
  Incremental Backup Pool = Incremental
  Differential Backup Pool = Differential
}
EOF

    # 创建存储池配置
    cat > /etc/bareos/bareos-dir.d/pool/DefaultPools.conf << EOF
Pool {
  Name = Full
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 90 days
  Maximum Volume Bytes = 100G
  Label Format = "Full-"
}

Pool {
  Name = Incremental
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 50G
  Label Format = "Inc-"
}

Pool {
  Name = Differential
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 60 days
  Maximum Volume Bytes = 75G
  Label Format = "Diff-"
}
EOF
}

4.3 存储初始化脚本

#!/bin/bash
# scripts/init-storage.sh
set -e

echo "Initializing Bareos Storage..."

# 创建存储目录
mkdir -p /bareos/storage/{full,inc,diff,archive}
chown -R bareos:bareos /bareos/storage
chmod -R 750 /bareos/storage

# 挂载外部存储(如果配置)
if [ -d /data/backup ]; then
    ln -sf /data/backup /bareos/storage/external
    chown -R bareos:bareos /data/backup
fi

# 配置S3存储(如果启用)
if [ ! -z "${AWS_ACCESS_KEY_ID}" ]; then
    echo "Configuring S3 storage..."

    # 创建S3配置文件
    cat > /etc/bareos/bareos-sd.d/device/S3Storage.conf << EOF
Device {
  Name = S3Storage
  Media Type = S3
  Archive Device = "s3://${S3_BUCKET_NAME}"
  Access Key ID = "${AWS_ACCESS_KEY_ID}"
  Secret Access Key = "${AWS_SECRET_ACCESS_KEY}"
  Endpoint = "${S3_ENDPOINT_URL}"
  Region = "${S3_REGION}"
  Chunk Size = 64M
  Multi Part Upload = yes
  Maximum Concurrent Jobs = 3
}
EOF
fi

echo "Storage initialization complete."
exec "$@"

五、部署与管理命令

5.1 部署脚本

#!/bin/bash
# deploy-bareos.sh
set -e

echo "=== Bareos Docker Deployment ==="

# 1. 创建目录结构
echo "Creating directory structure..."
mkdir -p {data/postgres,config,storage,logs,scripts,certs,letsencrypt}
mkdir -p config/{bareos-dir,bareos-sd,webui,prometheus,grafana}

# 2. 复制配置文件
echo "Copying configuration files..."
cp -r template-config/* config/

# 3. 设置权限
echo "Setting permissions..."
chmod 750 storage logs
chmod 600 .env

# 4. 加载环境变量
if [ -f .env ]; then
    export $(cat .env | grep -v '^#' | xargs)
fi

# 5. 启动服务
echo "Starting Bareos services..."
docker-compose up -d

# 6. 等待服务启动
echo "Waiting for services to start..."
sleep 30

# 7. 检查服务状态
echo "Checking service status..."
docker-compose ps

# 8. 初始化测试客户端
echo "Initializing test client configuration..."
./scripts/add-test-client.sh

# 9. 显示访问信息
echo "=== Deployment Complete ==="
echo "WebUI: http://localhost (or https://backup.company.com)"
echo "Director Console: docker exec -it bareos-director bconsole"
echo "Logs: docker-compose logs -f"
echo "Monitoring:"
echo "  - Prometheus: http://localhost:9090"
echo "  - Grafana: http://localhost:3000 (admin/${GRAFANA_PASSWORD})"

5.2 管理命令集合

#!/bin/bash
# bareos-manager.sh

case "$1" in
    start)
        docker-compose up -d
        ;;
    stop)
        docker-compose down
        ;;
    restart)
        docker-compose restart
        ;;
    status)
        docker-compose ps
        ;;
    logs)
        docker-compose logs -f $2
        ;;
    console)
        docker exec -it bareos-director bconsole
        ;;
    backup-now)
        docker exec bareos-director bconsole << EOF
run job=$2
yes
EOF
        ;;
    list-jobs)
        docker exec bareos-director bconsole << EOF
list jobs
EOF
        ;;
    list-clients)
        docker exec bareos-director bconsole << EOF
list clients
EOF
        ;;
    restore)
        docker exec bareos-director bconsole << EOF
restore client=$2
yes
EOF
        ;;
    add-client)
        # 添加新客户端
        CLIENT_NAME=$2
        CLIENT_IP=$3
        ./scripts/add-client.sh $CLIENT_NAME $CLIENT_IP
        ;;
    update)
        # 滚动更新
        docker-compose pull
        docker-compose up -d
        ;;
    backup-db)
        # 备份数据库
        docker exec bareos-db pg_dump -U bareos bareos > backup/bareos-db-$(date +%Y%m%d).sql
        ;;
    monitor)
        # 显示监控信息
        watch -n 5 'docker stats --no-stream bareos-postgres bareos-director bareos-storage bareos-webui'
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|status|logs|console|backup-now|list-jobs|list-clients|restore|add-client|update|backup-db|monitor}"
        exit 1
        ;;
esac

六、生产环境优化

6.1 性能调优配置

# docker-compose.override.yml(生产环境)
version: '3.8'
services:
  bareos-db:
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: '2'
        reservations:
          memory: 2G
          cpus: '1'
    command: >
      postgres
      -c shared_buffers=1GB
      -c effective_cache_size=3GB
      -c maintenance_work_mem=256MB
      -c checkpoint_completion_target=0.9
      -c wal_buffers=16MB
      -c default_statistics_target=100
      -c random_page_cost=1.1
      -c effective_io_concurrency=200
      -c work_mem=10485kB
      -c min_wal_size=1GB
      -c max_wal_size=4GB
      -c max_connections=200
      -c max_worker_processes=8
      -c max_parallel_workers_per_gather=4
      -c max_parallel_workers=8
      -c max_parallel_maintenance_workers=4

  bareos-director:
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: '2'
        reservations:
          memory: 2G
          cpus: '1'
    environment:
      BAREOS_MAX_JOBS: 50
      JAVA_OPTS: "-Xmx2g -Xms1g"
    ulimits:
      nofile:
        soft: 65536
        hard: 65536

  bareos-storage:
    deploy:
      resources:
        limits:
          memory: 8G
          cpus: '4'
        reservations:
          memory: 4G
          cpus: '2'
    volumes:
      - /dev/sdb:/dev/sdb:rw  # 直通存储设备
      - /mnt/ssd_cache:/cache:rw  # SSD缓存
    sysctls:
      - net.core.rmem_max=134217728
      - net.core.wmem_max=134217728
      - net.ipv4.tcp_rmem='4096 87380 134217728'
      - net.ipv4.tcp_wmem='4096 65536 134217728'

6.2 高可用配置

# docker-compose.ha.yml(高可用配置)
version: '3.8'
services:
  # PostgreSQL高可用(使用Patroni)
  postgresql:
    image: bitnami/postgresql-repmgr:15
    deploy:
      replicas: 3
      placement:
        constraints:
          - node.role == manager
    environment:
      POSTGRESQL_POSTGRES_PASSWORD: ${DB_ROOT_PASSWORD}
      POSTGRESQL_PASSWORD: ${DB_PASSWORD}
      POSTGRESQL_DATABASE: bareos
      POSTGRESQL_USERNAME: ${DB_USER}
      REPMGR_PASSWORD: ${REPMGR_PASSWORD}
      REPMGR_PRIMARY_HOST: postgresql-0
      REPMGR_PARTNER_NODES: postgresql-0,postgresql-1,postgresql-2
      REPMGR_NODE_NAME: postgresql-${REPLICA_NUMBER}
      REPMGR_NODE_NETWORK_NAME: postgresql-${REPLICA_NUMBER}

  # Bareos Director集群
  bareos-director:
    deploy:
      replicas: 2
      placement:
        constraints:
          - node.role == manager
    environment:
      BAREOS_DIR_CLUSTER: "true"
      BAREOS_DIR_PEERS: "bareos-director-0:9101,bareos-director-1:9101"

  # 负载均衡器
  haproxy:
    image: haproxy:2.8
    ports:
      - "9101:9101"  # Director
      - "9103:9103"  # Storage
      - "80:80"      # WebUI
    configs:
      - source: haproxy.cfg
        target: /usr/local/etc/haproxy/haproxy.cfg

七、备份策略配置

7.1 Docker Compose备份配置

# docker-compose.backup.yml(备份Bareos自身)
services:
  # Bareos自身备份
  bareos-self-backup:
    image: alpine:latest
    container_name: bareos-self-backup
    restart: "no"  # 手动触发
    networks:
      - bareos-net
    volumes:
      - ./data:/backup/data:ro
      - ./config:/backup/config:ro
      - ./storage:/backup/storage:ro
    command: >
      sh -c "
      # 备份数据库
      PGPASSWORD=$${DB_PASSWORD} pg_dump -h bareos-db -U $${DB_USER} bareos > /backup/data/bareos-db-$$(date +%Y%m%d).sql

      # 备份配置文件
      tar czf /backup/config-$$(date +%Y%m%d).tar.gz -C /backup/config .

      # 上传到S3
      apk add --no-cache aws-cli
      aws s3 cp /backup/data/bareos-db-$$(date +%Y%m%d).sql s3://$${S3_BUCKET_NAME}/bareos-metadata/
      aws s3 cp /backup/config-$$(date +%Y%m%d).tar.gz s3://$${S3_BUCKET_NAME}/bareos-config/
      "
    environment:
      - DB_PASSWORD
      - DB_USER
      - S3_BUCKET_NAME
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY

八、监控与告警配置

8.1 Prometheus配置

# config/prometheus/prometheus.yml
global:
  scrape_interval: 30s
  evaluation_interval: 30s

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

rule_files:
  - "alerts/*.yml"

scrape_configs:
  - job_name: 'bareos'
    static_configs:
      - targets: ['bareos-director:9625']
    metrics_path: /metrics
    scrape_interval: 15s

  - job_name: 'docker'
    static_configs:
      - targets: ['bareos-db:9100', 'bareos-director:9100', 'bareos-storage:9100']

  - job_name: 'postgres'
    static_configs:
      - targets: ['bareos-db:9187']

  - job_name: 'node'
    static_configs:
      - targets: ['node-exporter:9100']

8.2 Grafana仪表板导入

// config/grafana/dashboards/bareos.json
{
  "dashboard": {
    "title": "Bareos Backup System",
    "panels": [
      // 备份成功率
      {
        "title": "Backup Success Rate",
        "type": "stat",
        "targets": [{
          "expr": "sum(rate(bareos_job_success_total[24h])) / sum(rate(bareos_job_total[24h])) * 100",
          "legendFormat": "{{job}}"
        }],
        "thresholds": {
          "steps": [
            {"color": "red", "value": null},
            {"color": "yellow", "value": 95},
            {"color": "green", "value": 99}
          ]
        }
      },
      // 存储使用情况
      {
        "title": "Storage Usage",
        "type": "gauge",
        "targets": [{
          "expr": "bareos_storage_used_bytes / bareos_storage_total_bytes * 100",
          "legendFormat": "{{device}}"
        }]
      }
    ]
  }
}

九、安全加固

9.1 安全配置脚本

#!/bin/bash
# security-harden.sh

echo "Applying security hardening for Bareos Docker..."

# 1. 设置适当的文件权限
chmod 750 ./config ./scripts
chmod 600 .env
find ./config -type f -name "*.conf" -exec chmod 640 {} \;

# 2. 生成强密码
generate_password() {
    openssl rand -base64 32 | tr -d '/+=\n'
}

# 3. 更新.env文件中的密码
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$(generate_password)/" .env
sed -i "s/BAREOS_DIR_PASSWORD=.*/BAREOS_DIR_PASSWORD=$(generate_password)/" .env

# 4. 配置Docker安全选项
cat > docker-compose.security.yml << EOF
version: '3.8'
services:
  bareos-db:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
      - /run

  bareos-director:
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - DAC_OVERRIDE
      - SETGID
      - SETUID

  bareos-webui:
    security_opt:
      - no-new-privileges:true
    read_only: true
EOF

# 5. 启用审计日志
cat > config/audit.conf << EOF
# 审计配置
*.* /var/log/bareos/audit.log
& stop
EOF

echo "Security hardening complete."

十、故障排除

10.1 常见问题解决

#!/bin/bash
# troubleshoot.sh

echo "=== Bareos Troubleshooting ==="

# 1. 检查服务状态
check_services() {
    echo "1. Checking Docker services..."
    docker-compose ps
    docker-compose logs --tail=20 bareos-director
}

# 2. 检查网络连接
check_network() {
    echo "2. Checking network connectivity..."
    docker exec bareos-director ping -c 2 bareos-db
    docker exec bareos-director ping -c 2 bareos-storage
    docker exec bareos-director nc -zv bareos-db 5432
    docker exec bareos-director nc -zv bareos-storage 9103
}

# 3. 检查数据库
check_database() {
    echo "3. Checking database..."
    docker exec bareos-db psql -U bareos -d bareos -c "\dt"
    docker exec bareos-db psql -U bareos -d bareos -c "SELECT COUNT(*) FROM Job;"
}

# 4. 检查存储
check_storage() {
    echo "4. Checking storage..."
    docker exec bareos-storage ls -la /bareos/storage/
    docker exec bareos-storage df -h
}

# 5. 测试备份
test_backup() {
    echo "5. Testing backup functionality..."
    docker exec bareos-director bconsole << EOF
status director
status storage
list jobs last
run job=test-backup
yes
EOF
}

case "$1" in
    all)
        check_services
        check_network
        check_database
        check_storage
        test_backup
        ;;
    services) check_services ;;
    network) check_network ;;
    db) check_database ;;
    storage) check_storage ;;
    test) test_backup ;;
    *)
        echo "Usage: $0 {all|services|network|db|storage|test}"
        ;;
esac

这份详尽的容器化部署方案提供了: 1. 完整的生产就绪配置 2. 高可用和扩展选项 3. 全面的监控和安全 4. 详细的维护和排错指南

建议按照以下步骤实施: 1. 从基础配置开始测试 2. 逐步添加高可用和监控组件 3. 根据实际负载调整性能参数 4. 定期更新和维护

这样部署的Bareos系统将具备企业级可靠性,同时保持开源软件的成本优势。