Docker镜像全流程:从构建到实战

引言:我第一次接触镜像网站 ,是在撰写大学论文的过程中,是学校提供的由清华大学搭建的知网等镜像网站。之后又使用过清华源这类由清华大学提供的镜像站点。去年,我还见到有人搭建了专门用于访问 ChatGPT 的镜像网站,通过一个网页就能直接使用海量 ChatGPT 服务。

1、什么是「镜像网站」?

你可以理解成:把一个网站,完整复制一份,放到另一台服务器上。

2、为什么要做镜像?

①原版访问太慢 → 镜像更快②原版被封 / 打不开 → 镜像还能用③学校 / 公司内部用 → 不用连外网(国内网络受限导致知网无法正常下载、IP 不在授权池、网络出口限制、协议 / 域名拦截、跨网 / 跨境不稳定)

3、不是所有网站都能随便镜像!
受版权保护的(知网、论文、小说、影视)、有用户数据的、有商业利益的。

未经授权镜像 = 盗版 = 违法!

合法镜像只有两种:
官方允许你镜像
学校 / 机构购买授权(比如知网镜像)


Docker 镜像全流程:镜像构成 → 获取 → 查看 → 删除 → 手动定制 → Dockerfile 构建 → Web / 接口服务 → 跨域转发。


1. Docker 镜像是什么

Docker 镜像 = 只读模板,包含:

  • 基础操作系统(如 Ubuntu、Alpine)
  • 运行环境(JDK、Node、Python、Go)
  • 应用代码、依赖、配置
  • 启动命令

特点:

  • 分层存储(每一步操作都是一层)
  • 只读,容器运行时才加可写层
  • 可复用、可共享、可版本化

2. 镜像构成(核心:分层)

每一条指令 = 一层(Layer)

bash 复制代码
基础镜像层 ← FROM
依赖层     ← RUN apt install...
代码层     ← COPY / ADD
配置层     ← ENV / EXPOSE
启动层     ← CMD / ENTRYPOINT

层会被缓存,构建超快。


3. 获取镜像

bash 复制代码
docker pull 镜像名:标签

示例:

bash 复制代码
docker pull nginx:latest
docker pull python:3.11-slim
docker pull node:20-alpine

4. 列出本地镜像

bash 复制代码
docker images
# 或
docker image ls

展示:仓库名、标签、镜像 ID、大小、创建时间。


5. 删除本地镜像

bash 复制代码
# 按 镜像名:标签
docker rmi nginx:latest

# 按 镜像ID
docker rmi 镜像ID

# 强制删除
docker rmi -f 镜像ID

6. 定制镜像(两种方法)

方法 1:docker commit(手动打包)

  1. 先跑一个容器

    bash 复制代码
    docker run -it --name=mycontainer ubuntu bash
  2. 在里面装软件、改文件

  3. 退出后打包成新镜像

    bash 复制代码
    docker commit mycontainer my-ubuntu:v1

适合临时调试,不推荐生产。


方法 2:docker build + Dockerfile(标准、可复用)

最简单 Dockerfile 示例

bash 复制代码
FROM ubuntu:22.04
RUN apt update && apt install -y nginx
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

构建:

bash 复制代码
docker build -t my-web:v1 .

7. 构建 Web 镜像(实战)

1)创建文件

index.html

html 复制代码
<h1>My Docker Web</h1>

Dockerfile

bash 复制代码
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/
EXPOSE 80

2)构建

bash 复制代码
docker build -t my-web .

3)运行

bash 复制代码
docker run -d -p 8080:80 my-web

访问:http://localhost:8080


8. 构建 API 接口服务(以 Python FastAPI 为例)

main.py

python 复制代码
from fastapi import FastAPI
app = FastAPI()

@app.get("/api/hello")
def hello():
    return {"message": "Hello from Docker API"}

Dockerfile

bash 复制代码
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install fastapi uvicorn
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

运行:

bash 复制代码
docker run -p 8000:8000 my-api

接口:http://localhost:8000/api/hello


9. 跨域转发请求(Nginx 反向代理 + 跨域)

场景:

  • 前端 Web:my-web 容器
  • 后端 API:my-api 容器
  • Nginx 做转发 + 跨域

nginx.conf 关键配置

bash 复制代码
server {
    listen 80;
    location / {
        root /usr/share/nginx/html;
    }
    location /api/ {
        proxy_pass http://my-api:8000;
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods 'GET,POST,OPTIONS';
    }
}

Dockerfile

bash 复制代码
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY html /usr/share/nginx/html

这样就能:

  • 前端访问 /
  • API 访问 /api/xxx
  • 自动跨域

知网镜像网站搭建示例:

一、先懂:知网镜像是什么(对应镜像构成)

知网本地镜像 = 一套完整检索 + 存储 + Web 服务的只读 / 可更新镜像包,由同方知网授权提供。

  • 核心组件:检索引擎、文献数据库、Web 前端、CAJ 阅读器服务、后台管理
  • 架构分层(对应 Docker 分层):
    1. 基础层:CentOS/RedHat(知网官方推荐)
    2. 运行环境层:JDK8/11、Tomcat、MySQL/Oracle、Solr/Elasticsearch
    3. 应用层:CNKI 镜像系统(检索、全文、管理)
    4. 数据层:文献库、索引库(需单独挂载,不进镜像)
    5. 代理层:Nginx(反向代理、跨域、负载均衡)

二、准备阶段(获取镜像 / 环境)

1. 合法授权(必须)
  • 向同方知网签订本地镜像服务合同 ,获取:
    • 镜像安装包(ISO / 压缩包)
    • 授权文件(license)
    • 数据更新通道(每日 / 每月增量包)
  • 硬件:≥16 核、≥64G 内存、≥10T 存储(文献 + 索引)
2. Docker 环境准备
bash 复制代码
# 安装Docker
yum install -y docker-ce
systemctl start docker && systemctl enable docker

# 配置国内镜像源(加速)
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
EOF
systemctl restart docker

# 安装Docker Compose(编排多容器)
curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
3. 拉取基础镜像(获取镜像)
bash 复制代码
# 拉取官方基础镜像
docker pull centos:7
docker pull tomcat:9-jdk8
docker pull mysql:5.7
docker pull nginx:alpine
docker pull elasticsearch:7.17.9

# 查看本地镜像(列出镜像)
docker images

三、方式 1:docker commit 快速定制镜像(调试 / 临时)

适合快速打包已部署的知网环境,不推荐生产

  1. 运行基础容器并部署知网
bash 复制代码
# 启动CentOS容器
docker run -it --name cnki-base centos:7 bash

# 容器内安装JDK、Tomcat、MySQL、知网程序(同物理机部署)
# 配置license、数据库、索引、文献路径
# 测试访问正常后退出容器
exit
  1. commit 生成镜像
bash 复制代码
# 打包容器为镜像
docker commit cnki-base cnki-mirror:v1.0

# 查看
docker images | grep cnki
  1. 运行镜像
bash 复制代码
# 挂载数据卷(文献/索引/日志)
docker run -d \
  --name cnki-server \
  -p 8080:8080 \
  -v /data/cnki/db:/opt/cnki/db \
  -v /data/cnki/literature:/opt/cnki/literature \
  -v /data/cnki/index:/opt/cnki/index \
  cnki-mirror:v1.0

四、方式 2:Dockerfile + docker build 标准构建(生产推荐)

1. 目录结构
bash 复制代码
cnki-docker/
├── Dockerfile          # 主构建文件
├── docker-compose.yml  # 多容器编排
├── tomcat/             # Tomcat配置、知网war包
├── mysql/              # MySQL初始化脚本
├── nginx/              # Nginx反向代理+跨域配置
├── elasticsearch/      # ES索引配置
└── data/               # 数据卷目录(db/literature/index)
2. 核心 Dockerfile(构建 Web/Server 镜像)
bash 复制代码
# 基础层:CentOS7 + JDK8
FROM centos:7
MAINTAINER cnki-admin

# 安装依赖
RUN yum install -y wget tar vim && yum clean all

# 安装JDK8
COPY jdk-8u371-linux-x64.tar.gz /opt/
RUN tar -zxf /opt/jdk-8u371-linux-x64.tar.gz -C /opt/ && \
    ln -s /opt/jdk1.8.0_371 /opt/jdk && \
    rm -f /opt/jdk-8u371-linux-x64.tar.gz

# 环境变量
ENV JAVA_HOME=/opt/jdk
ENV PATH=$JAVA_HOME/bin:$PATH

# 安装Tomcat9
COPY apache-tomcat-9.0.75.tar.gz /opt/
RUN tar -zxf /opt/apache-tomcat-9.0.75.tar.gz -C /opt/ && \
    ln -s /opt/apache-tomcat-9.0.75 /opt/tomcat && \
    rm -f /opt/apache-tomcat-9.0.75.tar.gz

# 部署知网Web应用(war包来自同方授权)
COPY tomcat/cnki-web.war /opt/tomcat/webapps/
COPY tomcat/server.xml /opt/tomcat/conf/
COPY tomcat/cnki-license.xml /opt/cnki/conf/

# 暴露端口
EXPOSE 8080 8005 8009

# 启动命令
CMD ["/opt/tomcat/bin/catalina.sh", "run"]
3. 构建镜像
bash 复制代码
# 在cnki-docker目录执行
docker build -t cnki-web:v1.0 .

# 查看
docker images
4. Docker Compose 编排(多服务:Web+DB+ES+Nginx)

docker-compose.yml(核心)

bash 复制代码
version: '3.8'

services:
  # MySQL数据库
  mysql:
    image: mysql:5.7
    container_name: cnki-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: cnki123456
      MYSQL_DATABASE: cnki_db
    volumes:
      - ./data/mysql:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3306:3306"

  # Elasticsearch检索引擎
  elasticsearch:
    image: elasticsearch:7.17.9
    container_name: cnki-es
    restart: always
    environment:
      - discovery.type=single-node
      - ES_JAVA_OPTS=-Xms16g -Xmx16g
    volumes:
      - ./data/es:/usr/share/elasticsearch/data
      - ./elasticsearch/config:/usr/share/elasticsearch/config
    ports:
      - "9200:9200"

  # 知网Web服务
  cnki-web:
    build: .
    container_name: cnki-web
    restart: always
    depends_on:
      - mysql
      - elasticsearch
    volumes:
      - ./data/literature:/opt/cnki/literature
      - ./data/index:/opt/cnki/index
      - ./tomcat/logs:/opt/tomcat/logs
    ports:
      - "8080:8080"

  # Nginx反向代理+跨域
  nginx:
    image: nginx:alpine
    container_name: cnki-nginx
    restart: always
    depends_on:
      - cnki-web
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/logs:/var/log/nginx
    ports:
      - "80:80"
      - "443:443"
5. Nginx 跨域 + 转发配置(创建接口服务 + 跨域转发)

nginx/conf.d/cnki.conf

bash 复制代码
server {
    listen 80;
    server_name cnki-mirror.your-inst.edu.cn;

    # 主站转发
    location / {
        proxy_pass http://cnki-web:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # API接口跨域(检索/下载接口)
    location /api/ {
        proxy_pass http://cnki-web:8080/api/;
        # 跨域配置
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
        add_header Access-Control-Allow-Headers Content-Type;
        # 预检请求处理
        if ($request_method = OPTIONS) {
            return 204;
        }
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|ico)$ {
        proxy_pass http://cnki-web:8080;
        expires 7d;
    }
}
6. 一键启动
bash 复制代码
# 构建并启动所有服务
docker-compose up -d

# 查看容器状态
docker-compose ps

# 查看日志
docker-compose logs -f cnki-web

五、数据更新与维护(镜像管理)

1. 数据更新(同方提供增量包)
bash 复制代码
# 停止Web服务
docker-compose stop cnki-web

# 解压更新包到数据卷
tar -zxf cnki-update-20260221.tar.gz -C ./data/literature/

# 重建索引(容器内执行)
docker exec -it cnki-web /opt/cnki/bin/rebuild-index.sh

# 启动服务
docker-compose start cnki-web
2. 镜像管理
bash 复制代码
# 列出镜像
docker images

# 删除旧镜像
docker rmi cnki-web:v0.9

# 清理悬空镜像
docker image prune -f

# 导出镜像(备份/迁移)
docker save -o cnki-web-v1.0.tar cnki-web:v1.0

# 导入镜像
docker load -i cnki-web-v1.0.tar

六、访问与验证

  • 浏览器访问:http://你的服务器IPhttp://cnki-mirror.your-inst.edu.cn
  • 验证:检索文献、下载 CAJ/PDF、接口跨域调用正常

七、关键合规与技术要点

  1. 必须授权:无同方授权的镜像均为盗版,涉嫌侵权
  2. 数据隔离 :文献 / 索引 / 数据库必须用数据卷挂载,不打包进镜像
  3. 性能优化:ES 内存≥16G、Tomcat 连接池调优、Nginx 缓存
  4. 安全:限制 IP 访问、启用 HTTPS、定期更新系统与镜像
相关推荐
李小白杂货铺2 年前
国内开源软件镜像站点参考
开源软件·镜像·系统软件·镜像站点·镜像网站