从零到一:我用 Docker 把项目部署到服务器,只用了这 5 步(附避坑经验)

为什么你的项目总在“环境”上翻车?

相信不少开发者都有过这样的经历:本地跑得飞起的代码,一上服务器就报错。数据库版本不一致、依赖冲突、系统库缺失……这些“环境玄学”往往比写代码本身更让人头疼。而 Docker 的出现,彻底解决了这个问题。它把整个运行环境打包成一个“集装箱”,无论你在哪里运行,结果都是一致的。

今天,站长就带你从零开始,手把手完成一次完整的 docker 部署 实战。读完这篇文章,你不仅能掌握部署的完整流程,还能避开那些新手最容易踩的坑。

第一步:准备工作——选服务器与装 Docker

在开始之前,你需要一台云服务器。这里笔者建议选择主流的云服务商(如阿里云、腾讯云、华为云等),系统推荐 Ubuntu 20.04 或 CentOS 7.x。购买时注意选择靠谱的配置,2核4G 起步对于大多数中小型项目已经足够。

连接上服务器后,我们开始安装 Docker。执行以下命令(以 Ubuntu 为例):

# 更新软件源
sudo apt update

# 安装依赖包
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

# 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

# 验证安装
sudo docker --version

看到版本号输出,说明 Docker 安装成功。记得将当前用户加入 docker 组,避免每次使用 sudo:sudo usermod -aG docker $USER,然后重新登录。

第二步:编写 Dockerfile——把你的应用“装进箱子”

假设我们有一个基于 Node.js 的 Express 应用。在项目根目录下创建 Dockerfile 文件,内容如下:

# 基于官方 Node.js 镜像
FROM node:18-alpine

# 设置工作目录
WORKDIR /app

# 先复制 package.json,利用 Docker 缓存层
COPY package.json ./

# 安装依赖
RUN npm install --production

# 复制项目代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "server.js"]

关键点解析:

  • 选择 Alpine 版本:镜像体积小,部署更快。
  • 分层构建:先复制 package.json 再安装依赖,如果源码改了但依赖没变,Docker 会直接使用缓存层,大幅缩短构建时间。
  • EXPOSE 只是声明:真正暴露端口需要在运行容器时用 -p 参数指定。

如果你用的是其他语言(如 Python、Java、Go),原理完全一样,只是基础镜像和命令不同。比如 Python 项目:

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

第三步:构建镜像与运行容器

在项目根目录下执行:

# 构建镜像,-t 指定标签名
docker build -t my-app:v1 .

# 查看本地镜像
docker images

构建成功后,运行容器:

# 后台运行,将容器的 3000 端口映射到宿主机的 8080 端口
docker run -d --name my-app-container -p 8080:3000 my-app:v1

# 查看运行中的容器
docker ps

# 查看日志
docker logs my-app-container

此时,访问 http://你的服务器IP:8080 就能看到你的应用了。

常见问题:

  • 端口被占用:检查 sudo lsof -i:8080,换一个端口即可。
  • 容器启动后立即退出:用 docker logs 容器ID 查看错误日志,通常是代码或配置问题。

第四步:使用 Docker Compose 管理多服务

如果你的项目需要数据库、缓存等配套服务(比如 Node.js + MySQL + Redis),手动管理多个容器会很麻烦。这时 Docker Compose 就派上用场了。

在项目目录下创建 docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:3000"
    depends_on:
      - db
      - redis
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  db_data:

然后一键启动所有服务:

docker-compose up -d

停止和删除:docker-compose down。注意,volumes 配置了数据持久化,即使容器删除,数据库文件也不会丢失。

第五步:生产环境优化与安全加固

本地跑通了,不代表生产环境就稳了。以下是站长总结的几个关键优化点:

1. 镜像瘦身

使用多阶段构建,只保留最终产物。例如 Go 项目:

# 第一阶段:编译
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .

# 第二阶段:运行
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]

这样最终镜像只有几十 MB,而不是几百 MB。

2. 使用非 root 用户

默认容器以 root 运行,存在安全隐患。在 Dockerfile 中添加:

RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

3. 日志管理

限制日志文件大小,防止撑爆磁盘:

docker run -d --log-opt max-size=10m --log-opt max-file=3 my-app:v1

4. 健康检查

在 Dockerfile 或 docker-compose.yml 中添加健康检查:

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

5. 资源限制

防止单个容器占用全部资源:

docker run --memory="512m" --cpus="1.0" my-app:v1

避坑指南:新手最容易翻车的 3 个点

表现 解决方法
时区问题 日志时间比实际晚 8 小时 在 Dockerfile 中添加 ENV TZ=Asia/Shanghai
文件权限 容器内无法写入挂载目录 确保宿主机目录权限为 777,或使用 user: 1000:1000 指定 UID
网络连接 容器无法访问宿主机服务 使用 host.docker.internal 代替 localhost

部署后的下一步

当你的应用稳定运行后,可以考虑配置 域名HTTPS。购买一个正规域名,使用 Nginx 反向代理到 Docker 容器,再用 Let’s Encrypt 免费申请 SSL 证书。这样你的服务就真正“上线”了,用户可以通过域名安全访问。

如果你需要长期运营,建议选择靠谱的云服务商,购买带数据盘的服务器,并将 Docker 的数据目录迁移到数据盘上,避免系统盘被写满导致服务异常。

Docker 部署的本质是“一次构建,到处运行”。掌握这套流程后,无论你是部署个人博客、API 服务还是微服务架构,都能游刃有余。希望这篇文章能帮你少走弯路,顺利把项目跑在云端。

💡 【站长特惠服务推荐】

新手搭建网站或部署容器,推荐选择高性价比独享云服务器。点击下方通道可享受限时折扣与专属优惠券:

👉 点此前往领取云服务器限时优惠券

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部