嘿,大家好!今天咱们聊个运维圈的经典笑话:一个实习生上生产环境,直接给所有文件设成 777 权限,结果 SSH 都连不上了。这事儿听着好笑,但真碰上了就头疼了。

咱们就从这个糗事儿出发,聊聊实习生上生产环境该咋给自己设权限,尤其是部署一个 Spring Boot 的 Docker 服务,到底得用哪些命令,咋做才靠谱。

咱从最简单的想法开始,一步步推到现代化的方案,顺便看看简单方法有啥坑,再想想咋优化到主流水平。

最简单的想法:啥都给 777

假设你是那个实习生,刚拿到一台生产服务器,想部署个 Spring Boot 应用,跑在 Docker 里。你一琢磨,权限不够咋办?简单,直接全开:

chmod -R 777 /app

这命令把 /app 目录下所有文件都改成读写执行随便来。然后你兴冲冲地跑 Docker:

docker run -d -p 8080:8080 my-springboot-app

结果呢?服务倒是跑起来了,但问题大了——SSH 连不上,服务器直接“裸奔”。为啥?777 太猛了,连系统关键文件都被改了权限,SSH 服务依赖的配置可能都废了。这就是传说中的“777惨案”。

简单方法的坑在哪

这最原始的法子看着省事,但毛病不少:

  • 安全炸了:所有人都能读写执行,别人随便改个文件,服务就挂了。

  • 误伤系统:-R 是递归改,连不该动的系统文件都中招,SSH 挂掉只是开始。

  • 没必要:部署 Spring Boot 压根不需要这么大权限,白白增加了风险。

这法子显然不行,得想想更靠谱的路子。实习生上生产环境,到底该给自己啥权限呢?

第一步改进:最小权限试试

咱们冷静下来,部署 Spring Boot 的 Docker 服务,到底需要啥?一般是:

  1. 放文件的目录(比如 /app)得能写。

  2. Docker 得能跑,涉及 docker 命令的执行权限。

  3. 不能随便改系统文件。

那就别用 777 了,试试最小权限。比如你是用户 dev,先建个目录:

mkdir /app
chown dev:dev /app
chmod 700 /app

700 是啥意思?用户 dev 有读写执行(4+2+1=7),其他人啥权限都没。这样 /app 归你管,安全多了。然后写个 Dockerfile,把 Spring Boot 应用打包:

FROM openjdk:17
COPY target/myapp.jar /app/myapp.jar
WORKDIR /app
CMD ["java", "-jar", "myapp.jar"]

构建镜像:

bash体验AI代码助手代码解读复制代码docker build -t my-springboot-app .

跑容器:

bash体验AI代码助手代码解读复制代码docker run -d -p 8080:8080 -v /app:/app my-springboot-app

这里 -v 把宿主机的 /app 挂载到容器里,权限够用,服务也能跑。但你试了试,发现 Docker 报错:permission denied。咋回事?原来 docker 命令需要 root 权限,你得加 sudo:

bash体验AI代码助手代码解读复制代码sudo docker run -d -p 8080:8080 -v /app:/app my-springboot-app

这下好了吧?服务跑起来了,权限也没乱给。但还是有点别扭,手动加 sudo 太麻烦,而且 /app 里文件的权限还得再调调。

再优化:贴近生产环境

光这样还不够,生产环境不会让你随便用 root 跑东西。主流做法是啥呢?得用个专门的用户管服务,别直接拿自己的账号干活。咱们再改改:

  1. 创建个服务用户,比如 springuser:

sudo useradd -m springuser
sudo passwd springuser  # 设置密码
  1. 把 /app 给这个用户:

sudo mkdir /app
sudo chown springuser:springuser /app
sudo chmod 750 /app  # 用户读写执行,组读执行
  1. 切换到 springuser:

su - springuser
  1. 部署时,Docker 不一定需要 root,可以加到 docker 组:

sudo usermod -aG docker springuser

退出再登录,springuser 就能直接跑 docker 命令了。

然后构建和运行还是那套:

docker build -t my-springboot-app .
docker run -d -p 8080:8080 -v /app:/app my-springboot-app

这时候,/app 里文件的权限得再确认下。Spring Boot 的 jar 文件只需要读执行就够,改一下:

chmod 550 /app/myapp.jar

550 是用户和组可读可执行(4+1),别人没权限。服务跑得稳,权限也没乱放。

逼近主流:自动化与规范化

这套手动操作已经比 777 强多了,但离现代运维还有距离。生产环境里,手动敲命令早淘汰了,主流方案是用 CI/CD 管道 和 容器编排。咋弄呢?

1.用 GitHub Actions 自动部署:

  • 写个 workflow,push 代码后自动构建镜像,推到 Docker Hub。

  • SSH 到服务器,拉镜像跑容器。

2.Docker Compose 单机部署:

version: '3'
services:
  app:
    image: my-springboot-app
    ports:
      - "8080:8080"
    volumes:
      - /app:/app
    user: "springuser"

跑起来:

docker-compose up -d

3.Kubernetes 上集群:

定义个 Deployment,指定 securityContext 跑非 root 用户:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: springboot
  template:
    metadata:
      labels:
        app: springboot
    spec:
      securityContext:
        runAsUser: 1000  # springuser 的 UID
      containers:
      - name: app
        image: my-springboot-app
        ports:
        - containerPort: 8080

这些方案权限控制更细,部署也自动化,实习生再也不用手忙脚乱了。

优化方向:向主流靠拢

从最初的 777 到现在,问题暴露了一堆。基于这个案例,优化得往这些方向走:

  1. 最小权限:别乱给 777,用 750、550 这种精准权限。

  2. 专用用户:别拿 root 或个人账号跑服务,建个 springuser 专门干活。

  3. 组权限:加到 docker 组,避免每次 sudo。

  4. 自动化部署:用 CI/CD 或 Docker Compose,少手动操作。

  5. 容器安全:指定非 root 用户运行,像 Kubernetes 的 runAsUser。

这些都是现代运维的标配。数字上也得准,比如 750 是 7(读写执行)+ 5(读执行)+ 0,不能写成 751,不然 others 多了一份执行权限。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐