以随便做的一个demo项目为例

1. 文件结构以及dockerfile编写

1.1. 项目根目录下的文件结构如图

image

这个项目里的npm指令是直接在根目录运行的,故指令生成的package.json package-lock.json都在根目录。
前后端只在文件里有区分,实际的耦合还是偏多,部署时只用了一个docker镜像,没有分离成两个镜像,只能用于小项目。

1.2. dockerfile

# 使用 Node.js 基础镜像
FROM node:lts-alpine3.21

# 设置工作目录
WORKDIR /app

# 复制代码
COPY src .

# 安装后端依赖
RUN npm install

# 暴露后端端口
EXPOSE 3000

# 启动服务
CMD ["node", "backend/tle2orbit.js"]

这里的dockerfile是最基本的,也没用docker-compose。为了减少不必要的文件,只把src目录下的前后端文件复制到/app。
基础镜像的选择实际是比较复杂的,为了体积小传的快因此用的node:lts-alpine3.21
运行docker build -t orbit-display:test .指令前,需要注意的是dockerfile里的RUN npm install命令。复制的目录(/src)下必须要有package.json package-lock.json文件,因此对于前后端分离成两个docker的情况下,npm命令可能需要在frontendbackend两个文件中分别运行(?

1.3. 前后端分离成两个docker是更好的方法


AI

使用 Docker 来部署你的前后端应用非常方便,它可以将应用及其依赖环境封装在容器中,确保一致性和易管理性。

1. 准备环境

  1. 确保云服务器已安装 Docker 和 Docker Compose:
    sudo apt update
    sudo apt install docker.io docker-compose -y
  2. 启用 Docker 服务:
    sudo systemctl enable docker
    sudo systemctl start docker

2. 创建项目结构

在服务器或本地创建一个项目目录,整理文件结构:

docker-deployment/
    ├── frontend/
    │   ├── OrbitDisplay.html
    │   ├── cesium_script.js
    │   ├── Cesium/          # 如果有 Cesium 的依赖文件
    │   ├── Dockerfile       # 前端的 Dockerfile
    ├── backend/
    │   ├── server.js        # 假设后端入口是 server.js
    │   ├── package.json     # Node.js 后端的依赖文件
    │   ├── Dockerfile       # 后端的 Dockerfile
    ├── docker-compose.yml   # Docker Compose 配置文件

3. 前端 Dockerfile

frontend/ 目录下创建 Dockerfile

# 基于 Nginx 作为 Web 服务器
FROM nginx:latest

# 将前端代码复制到 Nginx 默认的静态文件目录
COPY . /usr/share/nginx/html

# 暴露 Nginx 默认端口
EXPOSE 80

# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

4. 后端 Dockerfile

backend/ 目录下创建 Dockerfile

# 使用 Node.js 基础镜像
FROM node:16

# 设置工作目录
WORKDIR /app

# 复制后端代码到容器
COPY . .

# 安装后端依赖
RUN npm install

# 暴露后端端口
EXPOSE 3000

# 启动后端服务
CMD ["node", "server.js"]

5. Docker Compose 配置

在项目根目录创建 docker-compose.yml 文件:

version: '3.8'

services:
  frontend:
    build:
      context: ./frontend
    ports:
      - "80:80" # 将容器的 80 端口映射到主机的 80 端口
    volumes:
      - ./frontend:/usr/share/nginx/html # 便于本地开发时实时同步

  backend:
    build:
      context: ./backend
    ports:
      - "3000:3000" # 将容器的 3000 端口映射到主机的 3000 端口
    volumes:
      - ./backend:/app # 便于本地开发时实时同步
    depends_on:
      - frontend

6. 构建和运行容器

  1. 在项目根目录下运行以下命令构建镜像:

    docker-compose build
  2. 启动服务:

    docker-compose up -d
  3. 查看运行中的容器:

    docker ps

7. 测试部署

  1. 访问前端页面:

    http://<your-server-ip>:80
    
  2. 验证前端是否能正常调用后端接口:

    • 检查浏览器的网络请求(Network)。
    • 确保后端返回正确的 JSON 数据。

8. 备选优化


最终目录结构

docker-deployment/
    ├── frontend/
    │   ├── OrbitDisplay.html
    │   ├── cesium_script.js
    │   ├── Cesium/
    │   ├── Dockerfile
    ├── backend/
    │   ├── server.js
    │   ├── package.json
    │   ├── Dockerfile
    ├── docker-compose.yml

通过以上步骤,可以用 Docker 将前端和后端打包为独立的服务并部署到云服务器上,便于管理和扩展。


2. docker镜像的编译

对于没有用docker-compose的项目,项目根目录下运行即可

docker build -t orbit-display:test .

image

计算机上没有基础镜像的会自动先下载基础镜像,因此可以提前下载基础镜像把步骤分开来。
如果使用了docker desktop则需要开着它编译。

编译好后就会出现你的镜像
image

3. docker镜像的部署

3.1. 最简单的方法是直接复制镜像文件

docker save -o <镜像文件名>.tar <镜像名>:<标签>
docker save -o Orbirt-Display.tar orbit-display:test

image

这会直接把镜像.tar文件保存到你运行指令的目录下,复制到服务器上,运行

docker load -i <文件名>.tar

无需解压就能加载镜像

加载完成后可以通过以下命令验证:

docker images

然后通过这个镜像创建容器

docker run -d --name orbit-display-http -p 80:3000 orbit-display:test

这样就在http的默认80端口创建了名字是orbit-display-http的容器

运行

docker start orbit-display-http

就能启动容器

可以使用以下指令查看运行状态等

docker stats orbit-display-http 
docker inspect orbit-display-http 

3.2. 使用Docker Hub——更加常用的方法


AI

push到Docker Hub上是更常用的办法

1. 在 Docker Hub 上准备镜像

登录 Docker Hub
推送镜像到 Docker Hub

如果镜像尚未上传到 Docker Hub,可以先将其推送:

  1. 给镜像打标签:

    docker tag <本地镜像名>:<标签> <DockerHub用户名>/<仓库名>:<标签>

    示例:

    docker tag my-app:latest myusername/my-app:1.0.0
  2. 推送到 Docker Hub:

    docker push <DockerHub用户名>/<仓库名>:<标签>

    示例:

    docker push myusername/my-app:1.0.0

2. 在服务器上部署镜像

登录 Docker Hub

在服务器上登录 Docker Hub:

docker login
拉取镜像

从 Docker Hub 拉取镜像:

docker pull <DockerHub用户名>/<仓库名>:<标签>

示例:

docker pull myusername/my-app:1.0.0
运行容器

使用拉取的镜像运行容器:

docker run -d --name <容器名> -p <宿主机端口>:<容器端口> <DockerHub用户名>/<仓库名>:<标签>

示例:

docker run -d --name my-app-container -p 8080:3000 myusername/my-app:1.0.0

3. 检查部署状态

查看运行中的容器
docker ps

输出示例:

CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                    NAMES
abc12345xyz    myusername/my-app:1.0.0  "npm start"             5 seconds ago    Up 5 seconds    0.0.0.0:8080->3000/tcp   my-app-container
访问应用

4. 自动化部署(可选)

为了简化未来更新,可以创建自动化流程。

使用 Docker Compose

编写一个 docker-compose.yml 文件:

version: '3'
services:
  my-app:
    image: myusername/my-app:1.0.0
    container_name: my-app-container
    ports:
      - "8080:3000"
    restart: always

启动服务:

docker-compose up -d
持续更新镜像

可以通过配置 Webhook 或使用 CI/CD 工具(如 GitHub Actions)自动将最新镜像推送到 Docker Hub并更新服务器。

5. 定期更新镜像

如果镜像在 Docker Hub 上更新了,可以拉取最新版本并重新启动容器:

  1. 拉取最新镜像:

    docker pull <DockerHub用户名>/<仓库名>:<标签>
  2. 停止旧容器并删除:

    docker stop <容器名>
    docker rm <容器名>
  3. 使用新镜像重新运行容器:

    docker run -d --name <容器名> -p <宿主机端口>:<容器端口> <DockerHub用户名>/<仓库名>:<标签>

3.3. 用于实际生产等也可以使用服务器提供商的流程


AI

传镜像到阿里云容器镜像服务

如果需要将镜像上传到阿里云容器镜像服务(ACR),请按照以下步骤操作:

1 登录阿里云容器镜像服务

在本地或服务器上使用 docker login 登录阿里云 ACR:

docker login --username=<阿里云账号或子账号> registry.cn-<地域>.aliyuncs.com

例如:

docker login --username=myusername registry.cn-shanghai.aliyuncs.com

2 给镜像打标签

为镜像添加阿里云 ACR 的标签:

docker tag <镜像名>:<标签> <阿里云镜像仓库地址>/<命名空间>/<镜像名>:<标签>

例如:

docker tag my_image:latest registry.cn-shanghai.aliyuncs.com/my_namespace/my_image:latest

3 推送镜像到 ACR

推送镜像到阿里云 ACR:

docker push <阿里云镜像仓库地址>/<命名空间>/<镜像名>:<标签>

例如:

docker push registry.cn-shanghai.aliyuncs.com/my_namespace/my_image:latest