登录
首页 >  文章 >  linux

阿里云ACR+ECS部署Spring项目教程

时间:2025-08-07 08:45:51 423浏览 收藏

IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《阿里云 ACR + ECS 部署 Spring 项目实战》,聊聊,我们一起来看看吧!

编写高效安全的 Dockerfile:使用多阶段构建,构建阶段用 maven 镜像编译项目,运行阶段使用 openjdk:17-jre-slim 轻量镜像,以非 root 用户运行,添加 HEALTHCHECK 健康检查,减小镜像体积并提升安全性;2. 部署到 ECS 的常见坑与优化:务必配置安全组开放应用端口,设置 JVM 内存参数如 -Xmx512m 防止 OOM,通过 -v 挂载卷实现日志和数据持久化,配置阿里云 Docker 镜像加速提升拉取速度,使用启动脚本配合 --restart=always 实现容器自愈;3. 集成 ACR 与 CI/CD 实现自动化部署:通过 Git 提交触发 CI/CD 流水线,自动构建 JAR 和 Docker 镜像,登录 ACR 推送镜像,再通过 SSH 或阿里云 API 在 ECS 上拉取新镜像并滚动更新容器,利用镜像标签(如 commit SHA)实现版本追踪和快速回滚,最终实现从代码提交到部署的全流程自动化。

阿里云 ACR 镜像服务 + ECS 实战部署 Spring 项目

部署 Spring 项目到阿里云 ECS 并结合 ACR 镜像服务,核心在于将 Spring 应用打包成 Docker 镜像,推送到 ACR,然后在 ECS 上拉取并运行该镜像。这是一种高效、可复用的自动化部署路径,它把应用运行时环境和代码都封装起来,极大简化了部署和运维的复杂度。

我个人觉得,要实现 Spring 项目在阿里云 ACR 和 ECS 上的实战部署,其实可以分解成几个关键步骤,每一步都有它自己的学问和可能遇到的坑。

首先,你得把你的 Spring 项目搞定,确保它能打成一个可执行的 JAR 包或者 WAR 包。接着,就是为这个应用写一个 Dockerfile,这是把应用“容器化”的关键一步。我通常会选择一个轻量级的 JDK 基础镜像,比如 openjdk:17-jre-slim,然后把 JAR 包复制进去,暴露端口。构建完 Docker 镜像后,下一步就是把它推送到阿里云容器镜像服务 ACR。这需要你在 ACR 创建一个仓库,然后登录 ACR 的 Docker 客户端,用 docker push 命令把本地构建好的镜像推上去。

在 ECS 这边,你需要一台安装了 Docker 环境的 Linux 实例。别忘了,安全组配置是重中之重,你得确保 Spring 应用监听的端口(比如 8080)在安全组里是开放的,否则外面根本访问不到。在 ECS 上登录 ACR 后,直接 docker pull 拉取你的镜像,然后用 docker run -d -p 80:8080 --name my-spring-app my-acr-repo/my-spring-image:latest 这样的命令就能把应用跑起来了。如果需要持久化数据或者日志,记得加上 -v 参数挂载数据卷。当然,生产环境可能还需要 Nginx 做反向代理,或者用阿里云的 SLB 做负载均衡,这些都是后话了。

如何为 Spring 项目编写一个高效且安全的 Dockerfile?

说实话,一个好的 Dockerfile 能省下你不少麻烦,尤其是在镜像体积和安全性上。我最喜欢用多阶段构建(Multi-stage builds),这简直是神器。它能让你在构建阶段用一个完整的 JDK 环境编译打包,而在最终的运行时镜像里,只保留一个精简的 JRE 环境和你的应用 JAR 包,这样能把镜像体积压缩到最小。

举个例子,你可以这样写:

# 阶段1: 构建阶段
FROM maven:3.8.5-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# 阶段2: 运行阶段
FROM openjdk:17-jre-slim
WORKDIR /app
# 复制构建阶段生成的jar包
COPY --from=build /app/target/*.jar app.jar
# 暴露Spring Boot默认端口
EXPOSE 8080
# 以非root用户运行,增加安全性
RUN groupadd --system springgroup && useradd --system --gid springgroup springuser
USER springuser
# 定义健康检查,Spring Boot Actuator的/actuator/health端点
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f http://localhost:8080/actuator/health || exit 1
# 启动Spring Boot应用
ENTRYPOINT ["java", "-jar", "app.jar"]

这里面,我特意用了 openjdk:17-jre-slim 这种轻量级的基础镜像,并且让应用以非 root 用户 springuser 运行,这能有效降低安全风险。HEALTHCHECK 指令也挺重要的,它能让 Docker 知道你的应用是不是真的“活”着,而不仅仅是容器在跑。

在 ECS 上部署 Docker 化 Spring 应用时,常见的坑和优化策略有哪些?

部署到 ECS 上,你总会遇到些意想不到的问题,这很正常。我踩过不少坑,最常见的几个:

  1. 安全组配置问题: 屡试不爽的坑。应用跑起来了,但外面访问不到,十有八九是安全组没开放对应的端口。每次部署前,我都会条件反射地去检查一遍。
  2. 内存不足(OOM): Spring 应用尤其是 Spring Boot,默认启动可能就吃掉不少内存。如果 ECS 实例规格太小,或者 JVM 启动参数没调好,很容易就 OOM 了。我通常会给 JVM 加上 -Xmx-Xms 参数来限制内存使用,比如 -Xmx512m -Xms256m。另外,也要留意 Docker 容器本身的内存限制,docker run --memory=512m 也能起到作用。
  3. 日志和数据持久化: 容器是短暂的,一旦容器被删除或更新,里面的数据就没了。所以,日志文件、上传的文件或者数据库数据,都得通过 -v 参数挂载到 ECS 宿主机上的目录,或者直接用阿里云的 NAS、OSS 等存储服务。
  4. Docker 镜像拉取速度: 有时候从 ACR 拉取镜像会很慢,尤其是第一次。你可以在 ECS 实例上配置 Docker 镜像加速器,阿里云提供了官方的加速器地址,能显著提高拉取速度。
  5. 启动脚本的健壮性: 生产环境我不会手动敲 docker run 命令。通常会写一个 shell 脚本,包含停止旧容器、删除旧容器、拉取新镜像、启动新容器等逻辑,并且加上 --restart=always 参数,确保容器异常退出后能自动重启。

优化方面,除了上面提到的,我还会关注 ECS 实例的规格选择,根据应用预估的并发量和资源消耗来定。另外,日志收集也很关键,我会考虑把容器日志通过 log-driver 或者 Sidecar 容器的方式,统一发送到阿里云日志服务 SLS,方便后续的查询和分析。

如何将 ACR 镜像服务与 CI/CD 流水线集成,实现 Spring 项目的自动化部署?

把 ACR 和 CI/CD 结合起来,才是真正释放生产力的王道。我个人用过 Jenkins、GitLab CI/CD 和阿里云效 CodePipeline,核心思路都差不多:代码一提交,就自动触发构建、打包、部署的流程。

一个典型的自动化部署流程大概是这样的:

  1. 代码提交触发: 开发者将代码推送到 Git 仓库(比如 GitLab、GitHub 或阿里云 CodeUp)。
  2. CI/CD 工具监听: CI/CD 工具检测到代码变更,触发预设的流水线。
  3. 项目构建: 流水线拉取最新代码,使用 Maven 或 Gradle 构建 Spring 项目,生成 JAR 包。
  4. Docker 镜像构建: 基于 JAR 包和 Dockerfile,构建新的 Docker 镜像。
  5. ACR 登录与推送: 使用 CI/CD 工具中配置的 ACR 登录凭证(通常是 AccessKey),登录 ACR,然后将新构建的镜像推送到 ACR 仓库。
  6. ECS 部署触发: 这是最关键的一步。流水线可以通过 SSH 连接到 ECS 实例,执行预先写好的部署脚本;或者通过阿里云的 OpenAPI/SDK 调用 ECS 相关的接口,比如运行命令等。这个脚本会负责拉取 ACR 中的最新镜像,停止旧的容器,并启动新的容器。

一个简单的 GitLab CI/CD 配置片段可能长这样:

stages:
  - build
  - deploy

build_image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login --username=$ACR_USERNAME --password=$ACR_PASSWORD registry.cn-hangzhou.aliyuncs.com
    - docker build -t registry.cn-hangzhou.aliyuncs.com/your-namespace/your-spring-app:$CI_COMMIT_SHORT_SHA .
    - docker push registry.cn-hangzhou.aliyuncs.com/your-namespace/your-spring-app:$CI_COMMIT_SHORT_SHA
  only:
    - master

deploy_to_ecs:
  stage: deploy
  image: alpine/ssh-client:latest
  script:
    - ssh -o StrictHostKeyChecking=no $ECS_USER@$ECS_HOST "
      docker login --username=$ACR_USERNAME --password=$ACR_PASSWORD registry.cn-hangzhou.aliyuncs.com &&
      docker pull registry.cn-hangzhou.aliyuncs.com/your-namespace/your-spring-app:$CI_COMMIT_SHORT_SHA &&
      docker stop my-spring-app || true &&
      docker rm my-spring-app || true &&
      docker run -d -p 80:8080 --name my-spring-app --restart=always registry.cn-hangzhou.aliyuncs.com/your-namespace/your-spring-app:$CI_COMMIT_SHORT_SHA
      "
  only:
    - master

这里 ACR_USERNAME, ACR_PASSWORD, ECS_USER, ECS_HOST 都是 CI/CD 工具的环境变量,用于安全地存储凭证。每次提交,都会用当前的 commit SHA 作为镜像标签,这样方便追溯和回滚。

说到回滚,自动化部署也得考虑这一点。如果新版本有问题,我通常会通过 CI/CD 界面手动触发一个任务,指定拉取并运行上一个稳定版本的镜像,这样就能快速恢复服务。这些都是在实践中慢慢摸索出来的,虽然过程有点折腾,但一旦搭建起来,部署效率真是质的飞跃。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>