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

Docker容器中Angular前端无法解析Go后端服务地址问题求助

问题描述

Docker容器创建成功,但前端发起HTTP请求到后端服务时失败,报错信息:

GET http://backend:8080/questions net::ERR_NAME_NOT_RESOLVED

前端请求URL为http://backend:8080/questions,Referrer Policy为strict-origin-when-cross-origin。

相关配置及代码如下:

docker-compose.yml

version: "3.8"
services:
  frontend:
    build: ./question-paper
    ports:
      - "4200:4200"

  backend:
    build: ./backend
    ports:
      - "8080:8080"
    environment:
      - DB_NAME=questions
      - DB_PORT=3306
      - DB_HOST=database
      - DB_PASSWD=root
      - DB_USER=root
    depends_on:
      - database

  database:
    image: mysql
    restart: always
    environment:
      MYSQL_DATABASE: questions
      MYSQL_PASSWORD: root
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3806:3306"
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/  # Check the path to init.sql
      - my-db:/var/lib/mysql

volumes:
  my-db:

Angular请求代码

import { HttpClient } from '@angular/common/http';
import { Questions } from '../model/question-model';
import { Observable } from 'rxjs';
import { Inject, Injectable } from '@angular/core';


@Injectable({
  providedIn: 'root',
})
export class QuestionService {
  constructor(private httpClient: HttpClient) {}

  GetQuestions(): any {
    return this.httpClient.get('http://backend:8080/questions');
  }
}

Go后端代码

func main(){
    mux := mux.NewRouter()
    handle := h.CORS(
        h.AllowedOrigins([]string{"*"}),
        h.AllowedMethods([]string{"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS"}),
        h.AllowedHeaders([]string{"Content-Type", "Authorization", "Origin", "Accept"}),
    )
    mux.HandleFunc("/questions", handlers.GetQuestions)
    http.ListenAndServe(":8080", handle(mux))
}
问题原因

错误的核心原因是:前端代码运行在用户的浏览器中,而非Docker容器内部。Docker Compose创建的内部网络DNS解析仅对容器生效,浏览器作为宿主机环境的应用,无法识别backend这个服务名,自然无法解析对应的IP地址,导致请求失败。

解决方案

以下是几种无需硬编码IP的优雅解决方案:

方案1:Angular代理配置(开发环境推荐)

利用Angular CLI的代理功能,将前端请求转发到后端容器:

  1. 在Angular项目根目录创建proxy.conf.json:
{
  "/api": {
    "target": "http://backend:8080",
    "secure": false,
    "pathRewrite": {
      "^/api": ""
    }
  }
}
  1. 修改angular.json,在projects -> [你的项目名] -> architect -> serve -> options中添加:
"proxyConfig": "proxy.conf.json"
  1. 调整前端请求代码为相对路径:
GetQuestions(): any {
  return this.httpClient.get('/api/questions');
}

启动Angular应用后,CLI会自动将/api开头的请求代理到http://backend:8080,同时解决跨域问题。

方案2:Nginx反向代理(生产环境推荐)

通过Nginx统一处理前端和后端请求,让浏览器通过同一域名访问,彻底避免跨域和DNS解析问题:

  1. 创建nginx.conf配置文件:
server {
  listen 80;

  # 处理前端静态资源
  location / {
    root /usr/share/nginx/html;
    try_files $uri $uri/ /index.html;
  }

  # 转发后端API请求
  location /api/ {
    proxy_pass http://backend:8080/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
  1. 修改docker-compose.yml,添加Nginx服务并调整前端、后端的端口暴露:
version: "3.8"
services:
  frontend:
    build: ./question-paper
    ports: [] # 不再暴露4200端口,仅内部网络访问

  backend:
    build: ./backend
    ports: [] # 不再暴露8080端口,仅内部网络访问
    environment:
      - DB_NAME=questions
      - DB_PORT=3306
      - DB_HOST=database
      - DB_PASSWD=root
      - DB_USER=root
    depends_on:
      - database

  database:
    image: mysql
    restart: always
    environment:
      MYSQL_DATABASE: questions
      MYSQL_PASSWORD: root
      MYSQL_ROOT_PASSWORD: root
    ports:
      - "3806:3306"
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/
      - my-db:/var/lib/mysql

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      # 生产环境需挂载Angular构建后的静态文件目录:
      # - ./question-paper/dist/[项目名]/:/usr/share/nginx/html
    depends_on:
      - frontend
      - backend

volumes:
  my-db:
  1. 前端请求代码改为/api/questions,浏览器请求Nginx后,会被转发到后端服务。

方案3:环境变量动态配置

通过Angular的环境变量,根据开发/生产环境动态设置后端地址:

  1. 修改开发环境配置src/environments/environment.ts:
export const environment = {
  production: false,
  backendUrl: 'http://localhost:8080'
};
  1. 修改生产环境配置src/environments/environment.prod.ts:
export const environment = {
  production: true,
  backendUrl: '/api'
};
  1. 调整前端请求代码:
import { environment } from '../../environments/environment';

// ...

GetQuestions(): any {
  return this.httpClient.get(`${environment.backendUrl}/questions`);
}

开发时利用Docker端口映射的localhost:8080访问后端,生产时配合Nginx反向代理使用相对路径。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:35:07