You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署Node.js应用至DigitalOcean Droplet遇端口占用问题求助

问题

我在DigitalOcean的Droplet上部署了一个简单的Node.js应用,原本运行正常。现在想给应用添加SSL证书,同时在同一Droplet上部署多个应用到不同域名,因此使用了Nginx。我已在Droplet上安装好Nginx,完成域名和SSL配置,主域名www.example.com可正常运行静态HTML文件。

但通过Github Actions部署应用时出现如下错误:

Error starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use.

我已按照DigitalOcean官方文档配置Nginx,请问现在该如何将Node.js应用部署到Nginx?需要修改服务器配置,还是更新Dockerfile或Actions文件?

附Dockerfile:

FROM node:20-alpine

WORKDIR /app

COPY package*.json ./

RUN yarn

COPY . .

EXPOSE 8080

CMD [ "yarn", "start" ]

附Actions文件:

name: Deploy to DigitalOcean

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4.0.0

      - name: Set up Docker
        uses: docker/setup-buildx-action@v2.10.0

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push image to Docker Hub
        uses: docker/build-push-action@v4.2.1
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/my-app:${{ github.sha }}
          build-args: |
            NODE_VERSION=20

      - name: Deploy to DigitalOcean Droplet
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.DROPLET_IP }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: 22
          script: |
            echo "Pulling Docker image..."
            docker pull ${{ secrets.DOCKERHUB_USERNAME }}/my-app:${{ github.sha }}

            echo "Stopping and removing existing container (if it exists)..."
            if docker ps -a | grep -q "my-app-container"; then
              docker stop my-app-container
              docker rm my-app-container
            fi

            echo "Starting a new container..."
            docker run -d --name my-app-container -p 80:8080 ${{ secrets.DOCKERHUB_USERNAME }}/my-app:${{ github.sha }}

解决方案

1. 修复端口冲突问题

错误根源是Nginx已经占用了80端口,而你的Docker命令试图将容器8080端口映射到主机80端口,导致端口冲突。需要修改Actions中的Docker运行命令,把容器端口映射到主机的非80/443端口(比如3000),同时限制容器仅在本地回环地址监听,避免直接暴露到公网:

修改Actions中docker run行内容:

docker run -d --name my-app-container -p 127.0.0.1:3000:8080 ${{ secrets.DOCKERHUB_USERNAME }}/my-app:${{ github.sha }}

2. 配置Nginx反向代理

在Nginx配置目录(通常为/etc/nginx/sites-available/)新建对应应用域名的配置文件,比如my-app.example.com,内容如下:

server {
    listen 80;
    server_name my-app.example.com;
    # 重定向HTTP请求到HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name my-app.example.com;

    # 填写你的SSL证书路径(例如Let's Encrypt颁发的证书)
    ssl_certificate /etc/letsencrypt/live/my-app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-app.example.com/privkey.pem;

    # 反向代理到Docker容器映射的本地端口
    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

执行以下命令启用配置并重启Nginx:

# 启用配置文件
sudo ln -s /etc/nginx/sites-available/my-app.example.com /etc/nginx/sites-enabled/
# 验证配置语法
sudo nginx -t
# 重启Nginx生效
sudo systemctl restart nginx

3. Dockerfile无需修改

你的Dockerfile配置正常,Node应用监听8080端口的设置不需要改动——我们只是通过端口映射和Nginx反向代理实现对外服务,不影响容器内部的端口监听逻辑。

内容的提问来源于stack exchange,提问作者kar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:13:15