基于Docker搭建国企版档案管理系统的全流程实操指南

一、技术架构与环境准备

针对国企对数据安全、合规性及国产化适配的高要求,本方案采用后端FastAPI + 前端Vue3 + 数据库PostgreSQL + 对象存储MinIO的架构。该架构满足等保2.0要求,支持三员管理(系统管理员、安全保密员、安全审计员)。所有组件均通过Docker容器化部署,确保环境一致性。

1. 安装基础环境

在CentOS 7.9或Ubuntu 20.04服务器上执行以下命令安装Docker及Docker Compose。请确保使用root用户或具有sudo权限的用户执行。

```bash 安装Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun systemctl start docker systemctl enable docker 安装Docker Compose curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose 验证安装 docker --version docker-compose --version ```

二、数据持久层配置

创建项目目录结构并配置数据库与对象存储。国企版系统必须保证数据的强一致性和持久化,因此我们将数据挂载到宿主机。

1. 目录初始化

```bash mkdir -p /data/archives/{postgres,minio,backend,frontend} cd /data/archives ```

2. 编写docker-compose.yml基础服务

创建docker-compose.yml文件,配置PostgreSQL和MinIO。国企版需强制开启SSL和数据持久化,这里使用内部网络通信,配置高强度的默认密码。

```yaml version: '3.8' services: PostgreSQL 数据库配置 db: image: postgres:14-alpine container_name: archives_db environment: POSTGRES_USER: arch_admin POSTGRES_PASSWORD: ArchSecure@2024 POSTGRES_DB: archives_db volumes: - ./postgres/data:/var/lib/postgresql/data ports: - "5432:5432" networks: - arch_net healthcheck: test: ["CMD-SHELL", "pg_isready -U arch_admin"] interval: 10s timeout: 5s retries: 5 restart: always MinIO 对象存储配置 minio: image: minio/minio:latest container_name: archives_minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minio_admin MINIO_ROOT_PASSWORD: MinioSecure@2024 volumes: - ./minio/data:/data ports: - "9000:9000" - "9001:9001" networks: - arch_net healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 restart: always networks: arch_net: driver: bridge ```

三、后端核心服务开发

进入/data/archives/backend目录,构建基于FastAPI的后端服务,实现三员权限控制与文件元数据管理。这是系统的核心,负责处理业务逻辑和数据交互。

1. 依赖配置

创建requirements.txt,明确指定版本以防止依赖冲突:

```text fastapi==0.104.1 uvicorn[standard]==0.24.0 sqlalchemy==2.0.23 psycopg2-binary==2.9.9 pydantic==2.5.0 python-multipart==0.0.6 minio==7.2.0 python-jose[cryptography]==3.3.0 passlib[bcrypt]==1.7.4 pydantic-settings==2.1.0 ```

2. 数据模型设计

创建models.py,定义用户角色(符合国企三员标准)和档案密级。此模型直接映射到数据库表结构。

```python from sqlalchemy import Column, Integer, String, DateTime, Text, Enum as SQLEnum, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship import datetime import enum Base = declarative_base() class UserRole(enum.Enum): SYS_ADMIN = "sys_admin" 系统管理员:负责系统配置 SEC_ADMIN = "sec_admin" 安全保密员:负责用户授权 AUDITOR = "auditor" 安全审计员:只读,负责审计日志 class DocLevel(enum.Enum): PUBLIC = "public" 公开 INTERNAL = "internal" 内部 SECRET = "secret" 秘密 TOP_SECRET = "top_secret" 机密 class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) username = Column(String(50), unique=True, index=True, nullable=False) hashed_password = Column(String(100), nullable=False) role = Column(SQLEnum(UserRole), nullable=False) full_name = Column(String(100)) is_active = Column(DateTime, default=datetime.datetime.utcnow) class Document(Base): __tablename__ = "documents" id = Column(Integer, primary_key=True, index=True) title = Column(String(200), nullable=False) file_path = Column(String(500), nullable=False) MinIO object name level = Column(SQLEnum(DocLevel), default=DocLevel.INTERNAL) uploader_id = Column(Integer, ForeignKey("users.id")) created_at = Column(DateTime, default=datetime.datetime.utcnow) content_hash = Column(String(64)) SHA256用于完整性校验 class AuditLog(Base): __tablename__ = "audit_logs" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey("users.id")) action = Column(String(50)) UPLOAD, DOWNLOAD, DELETE, LOGIN target_doc_id = Column(Integer, ForeignKey("documents.id"), nullable=True) ip_address = Column(String(50)) timestamp = Column(DateTime, default=datetime.datetime.utcnow) details = Column(Text) 操作详情JSON ```

3. 业务逻辑与接口实现

创建main.py,实现文件上传、下载及鉴权逻辑。为了演示清晰,此处省略了复杂的JWT生成解析过程,使用Token模拟,但在生产环境中必须替换为标准RSA签名JWT。

```python from fastapi import FastAPI, Depends, HTTPException, status, UploadFile, File, Form from fastapi.security import OAuth2PasswordBearer from sqlalchemy.orm import Session from typing import Optional, List import hashlib import io import json from datetime import timedelta from minio import Minio from minio.error import S3Error import os 引入模型 from models import Base, User, Document, AuditLog, UserRole, DocLevel from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker 配置 DATABASE_URL = "postgresql://arch_admin:ArchSecure@2024@db:5432/archives_db" MINIO_ENDPOINT = "minio:9000" MINIO_ACCESS_KEY = "minio_admin" MINIO_SECRET_KEY = "MinioSecure@2024" MINIO_BUCKET = "secure-archives" engine = create_engine(DATABASE_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) 初始化MinIO客户端 minio_client = Minio( MINIO_ENDPOINT, access_key=MINIO_ACCESS_KEY, secret_key=MINIO_SECRET_KEY, secure=False ) app = FastAPI(title="国企版档案管理系统API") 依赖项:获取数据库会话 def get_db(): db = SessionLocal() try: yield db finally: db.close() 启动事件:创建表和MinIO桶 @app.on_event("startup") def startup_event(): Base.metadata.create_all(bind=engine) if not minio_client.bucket_exists(MINIO_BUCKET): minio_client.make_bucket(MINIO_BUCKET) 模拟鉴权 oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)): 实际生产需解析JWT,这里简化为直接查询用户名 user = db.query(User).filter(User.username == token).first() if not user: raise HTTPException(status_code=401, detail="无效认证凭据") return user 权限检查装饰器工厂 def require_role(allowed_roles: List[UserRole]): async def role_checker(current_user: User = Depends(get_current_user)): if current_user.role not in allowed_roles: raise HTTPException(status_code=403, detail="权限不足,操作已被审计记录") return current_user return role_checker @app.post("/upload/") async def upload_document( file: UploadFile = File(...), title: str = Form(...), level: str = Form(...), current_user: User = Depends(require_role([UserRole.SYS_ADMIN, UserRole.SEC_ADMIN])), db: Session = Depends(get_db) ): 读取文件内容计算哈希 file_content = await file.read() file_hash = hashlib.sha256(file_content).hexdigest() 构造存储路径:/密级/年份/月份/哈希_原名 from datetime import datetime now = datetime.now() object_name = f"{level}/{now.year}/{now.month}/{file_hash}_{file.filename}" try: 上传到MinIO minio_client.put_object( MINIO_BUCKET, object_name, data=io.BytesIO(file_content), length=len(file_content), content_type=file.content_type ) 记录数据库元数据 new_doc = Document( title=title, file_path=object_name, level=DocLevel(level), uploader_id=current_user.id, content_hash=file_hash ) db.add(new_doc) db.flush() 获取ID 记录审计日志 log = AuditLog( user_id=current_user.id, action="UPLOAD", target_doc_id=new_doc.id, details=json.dumps({"filename": file.filename, "size": len(file_content)}) ) db.add(log) db.commit() return {"status": "success", "document_id": new_doc.id, "message": "文件上传并归档成功"} except S3Error as e: db.rollback() raise HTTPException(status_code=500, detail=f"对象存储错误: {e}") except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=str(e)) @app.get("/audit/logs") async def get_audit_logs( skip: int = 0, limit: int = 100, current_user: User = Depends(require_role([UserRole.AUDITOR])), db: Session = Depends(get_db) ): logs = db.query(AuditLog).order_by(AuditLog.timestamp.desc()).offset(skip).limit(limit).all() return logs ```

四、Dockerfile与容器编排

基于Docker搭建国企版档案管理系统的全流程实操指南

编写后端服务的Dockerfile并将其集成到docker-compose中,实现一键启动。

1. 后端Dockerfile

/data/archives/backend下创建Dockerfile

```dockerfile FROM python:3.9-slim WORKDIR /app 安装系统依赖 RUN apt-get update && apt-get install -y gcc libpq-dev && rm -rf /var/lib/apt/lists/ COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . 暴露端口 EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] ```

2. 完整docker-compose.yml

更新/data/archives/docker-compose.yml,追加后端服务配置。确保后端在数据库健康检查通过后再启动。

```yaml ... (保留之前的db和minio配置) backend: build: ./backend container_name: archives_backend command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload volumes: - ./backend:/app ports: - "8000:8000" environment: - DATABASE_URL=postgresql://arch_admin:ArchSecure@2024@db:5432/archives_db depends_on: db: condition: service_healthy minio: condition: service_healthy networks: - arch_net restart: always ```

五、系统部署与验证

1. 启动所有服务

/data/archives目录下执行以下命令,构建镜像并启动容器:

```bash docker-compose up -d --build ```

查看启动状态:

```bash docker-compose ps ```

2. 初始化三员数据

进入后端容器,使用Python脚本初始化三个核心管理员账号。这是国企系统合规运行的必要条件。

```bash docker exec -it archives_backend python ``` ```python 在Python交互环境中执行 from sqlalchemy.orm import sessionmaker from models import Base, User, UserRole from main import engine from passlib.context import CryptContext pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") Session = sessionmaker(bind=engine) db = Session() 密码加密 def get_password_hash(password): return pwd_context.hash(password) 创建系统管理员 admin = User(username="admin", hashed_password=get_password_hash("Admin@123"), role=UserRole.SYS_ADMIN, full_name="系统管理员") 创建安全保密员 sec_admin = User(username="sec_admin", hashed_password=get_password_hash("Sec@123"), role=UserRole.SEC_ADMIN, full_name="安全保密员") 创建安全审计员 auditor = User(username="auditor", hashed_password=get_password_hash("Audit@123"), role=UserRole.AUDITOR, full_name="安全审计员") try: db.add_all([admin, sec_admin, auditor]) db.commit() print("初始化成功") except Exception as e: print(f"初始化失败: {e}") finally: db.close() exit() ```

3. 接口功能测试

使用curl测试上传接口。这里使用sec_admin账号进行上传操作,验证权限控制和文件存储流程。

```bash 创建测试文件 echo "这是机密档案内容" > /tmp/secret_doc.txt 调用上传接口 (注意:实际中这里需要先获取Token,这里演示直接使用用户名作为Bearer Token的简化逻辑) curl -X POST "http://localhost:8000/upload/" \ -H "Authorization: Bearer sec_admin" \ -F "file=@/tmp/secret_doc.txt" \ -F "title=年度涉密计划" \ -F "level=secret" ```

预期返回结果:

```json {"document_id":1,"message":"文件上传并归档成功","status":"success"} ```

此时,一个符合国企基本安全要求的档案管理系统已部署完成。系统通过Docker实现了环境隔离,通过PostgreSQL保证了数据一致性,通过MinIO实现了非结构化数据的存储,并通过代码层面实现了三员分权与审计追踪。后续可根据实际需求接入前端Vue界面或对接LDAP统一认证。

AI咨询
热线电话

028-85154420

15388110056

全国售前咨询电话

扫码咨询
安答联动微信公众号二维码

微信扫码关注安答联动

申请试用
热线电话
申请试用

安答联动档案管理系统