ASP.NET Core + Vue 项目部署到Ubuntu云服务器:Docker Compose全流程实战
2026/6/24 2:15:46 网站建设 项目流程

前言

最近我把一个基于 ASP.NET Core 8.0 后端 + Vue 3 前端的个人作品集项目部署到了云服务器上。之前也踩了不少坑——镜像拉取超时、413上传文件大小限制、图标缓存、Docker Compose版本兼容问题……网上资料比较零散,我干脆把这次部署的完整过程整理成一篇文章,希望能给同样在折腾Docker部署的朋友一些参考。

项目基本情况

  • 后端:ASP.NET Core 8.0 Web API,提供 RESTful 接口

  • 前端:Vue 3 + Vite + Element Plus

  • 数据库:远程 MySQL(部署在同一台云服务器上)

  • 服务器:Ubuntu(x86_64架构)

  • 部署方式:Docker Compose(前端Nginx容器 + 后端ASP.NET Core容器)

最终访问方式

  • 前端入口:http://你的服务器IP:8888

  • 后端API通过Nginx反向代理转发,不对外直接暴露


一、环境准备

1.1 安装 Docker 和 Docker Compose

bash

# 安装 Docker sudo apt update sudo apt install docker.io # 安装 Docker Compose sudo apt install docker-compose

1.2 查看服务器架构(选择正确的镜像)

bash

lscpu | grep "Architecture" # 输出 x86_64 → 对应 linux-x64

1.3 创建项目目录

bash

mkdir -p /data/MyPortfolio cd /data/MyPortfolio

二、准备项目文件

2.1 目录结构

text

/data/MyPortfolio/ ├── docker-compose.yml ├── backend/ │ ├── Dockerfile │ └── publish/ # dotnet publish 发布文件 ├── frontend/ │ ├── Dockerfile │ ├── default.conf # Nginx 配置 │ └── dist/ # npm run build 构建产物

2.2 构建后端发布文件(本地或服务器上)

bash

# 在项目根目录执行 dotnet publish -c Release -o ./publish

然后将publish文件夹上传到/data/MyPortfolio/backend/

2.3 构建前端产物

bash

npm run build

dist文件夹上传到/data/MyPortfolio/frontend/


三、核心配置文件

3.1 后端 Dockerfile

/data/MyPortfolio/backend/Dockerfile

dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 8000 FROM base AS final WORKDIR /app COPY ./publish . ENTRYPOINT ["dotnet", "Portfolio.Api.dll"] # 替换为你的项目名

3.2 前端 Nginx 配置

/data/MyPortfolio/frontend/default.conf

注意proxy_pass中的backenddocker-compose.yml中定义的后端服务名,Docker内部DNS会自动解析。

nginx

server { listen 80; server_name your_domain_or_ip; # 允许上传最大 100MB 的文件(解决 413 错误) client_max_body_size 100M; root /usr/share/nginx/html; index index.html; # Vue Router 支持(刷新页面不404) location / { try_files $uri $uri/ /index.html; } # API 请求代理到后端容器 location ^~/api/ { proxy_pass http://backend:8000/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }

3.3 前端 Dockerfile

/data/MyPortfolio/frontend/Dockerfile

dockerfile

FROM nginx:alpine COPY default.conf /etc/nginx/conf.d/default.conf COPY dist /usr/share/nginx/html EXPOSE 80

3.4 Docker Compose 编排

/data/MyPortfolio/docker-compose.yml

yaml

version: '3.8' services: backend: build: context: ./backend dockerfile: Dockerfile container_name: portfolio-backend environment: - ASPNETCORE_URLS=http://+:8000 # 数据库连接字符串(请替换为实际信息) - ConnectionStrings__DefaultConnection=Server=your_db_host;Port=3306;Database=your_db;User=your_user;Password=your_password; restart: always frontend: build: context: ./frontend dockerfile: Dockerfile container_name: portfolio-frontend ports: - "8888:80" depends_on: - backend restart: always

四、部署过程中遇到的问题与解决

4.1 镜像拉取失败(DNS / 网络超时)

报错信息

text

failed to resolve reference "docker.io/library/nginx:alpine": dial tcp: lookup docker.mirrors.ustc.edu.cn on 127.0.0.53:53: no such host

原因分析

  • 服务器 DNS 解析有问题(127.0.0.53无法解析镜像源域名)

  • 配置的镜像加速器(中科大源)已失效

解决方案(临时):直接修改系统 DNS,并清空 Docker 镜像加速器。

bash

# 修改系统 DNS sudo systemctl stop systemd-resolved sudo systemctl disable systemd-resolved sudo rm -f /etc/resolv.conf sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf' sudo bash -c 'echo "nameserver 114.114.114.114" >> /etc/resolv.conf' # 修改 Docker 配置 sudo nano /etc/docker/daemon.json

写入:

json

{ "registry-mirrors": [], "dns": ["8.8.8.8", "114.114.114.114"] }

重启 Docker:

bash

sudo systemctl daemon-reload sudo systemctl restart docker

如果还是拉取失败,可以手动导入镜像:

bash

# 在能联网的机器上 docker pull nginx:alpine docker save nginx:alpine -o nginx-alpine.tar # 上传到服务器后 docker load -i nginx-alpine.tar

4.2 上传文件报 413 Request Entity Too Large

原因:Nginx 默认client_max_body_size为 1MB。

解决方案:在default.confserver块中添加:

nginx

client_max_body_size 100M;

然后重新构建前端镜像并重启:

bash

sudo docker-compose build --no-cache frontend sudo docker-compose up -d

4.3 Docker Compose 启动报错KeyError: 'ContainerConfig'

报错信息

text

KeyError: 'ContainerConfig'

原因:Docker Compose 版本较旧(1.29.2),或容器元数据损坏。

解决方案

bash

# 彻底清理 sudo docker-compose down --volumes --remove-orphans # 重新构建并启动 sudo docker-compose up -d

这个小技巧建议收藏,遇到奇奇怪怪的容器启动问题时特别好用。

4.4 Favicon 图标不更新

现象:部署新项目后,浏览器标签页还是显示旧项目的图标。

原因:浏览器独立缓存了favicon.ico,清除页面缓存无效。

解决方案

  1. 硬刷新:Ctrl + F5(Windows)或Cmd + Shift + R(Mac)

  2. 或使用无痕模式验证

  3. 永久解决:在index.html中给图标加版本号:

html

<link rel="icon" href="/favicon.ico?v=2" />

五、常用运维命令

5.1 查看容器状态

bash

sudo docker ps

5.2 查看容器日志

bash

# 查看后端日志 sudo docker logs -f portfolio-backend # 查看前端日志 sudo docker logs -f portfolio-frontend

5.3 进入容器调试

bash

# 进入前端容器 sudo docker exec -it portfolio-frontend /bin/sh # 进入后端容器 sudo docker exec -it portfolio-backend /bin/bash

5.4 停止并清理

bash

sudo docker-compose down sudo docker-compose down --volumes --remove-orphans # 完全清理

5.5 重启服务

bash

sudo docker-compose restart

六、小结

这次部署不算复杂,但踩的坑都挺典型的。总结几点经验:

  1. 国内服务器一定要配好DNS和镜像源,不然拉取镜像能卡半天。建议直接用阿里云或网易的镜像加速器,中科大的源现在不太稳定。

  2. Nginx 的client_max_body_size要记得配,否则文件上传超1MB就报413,排查起来容易被忽略。

  3. 遇到容器启动报KeyError,先docker-compose down --volumes --remove-orphans再重新up,能解决大部分元数据问题。

  4. 前端用相对路径/api/xxx请求,配合Nginx反向代理,可以避免跨域问题,部署也更灵活。

  5. 图标缓存问题,加?v=版本号是最高效的解决方式。

整个部署流程跑通后,后续更新就很简单了:本地修改代码 →publish/build→ 上传替换文件 →docker-compose build --no-cachedocker-compose up -d。一次配置,长期受益。


相关资源

  • Docker 官方文档

  • Nginx 配置文档

  • ASP.NET Core Docker 部署文档

希望这篇博客能帮到正在折腾Docker部署的你。如果遇到问题,欢迎在评论区留言交流!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询