我有一个与this one非常相似的问题。
我确实有一个Angular应用程序,该应用程序收集数据,然后通过REST Api处理这些数据。我可以很高兴地对这两个应用程序进行docker化,它们在本地运行良好,但是,当我尝试部署它们以使它们可以从“任何地方”访问时,我只能到达前端,但是与REST Api的连接不起作用。
在Angular应用程序中,我有一个文件baseurl.ts
。那只包含:
export const baseURL = 'http://localhost:3000/';
我使用以下方法准备好应用程序的生产
ng build --prod
这将创建dist
文件夹,然后创建以下docker容器(取自here):
FROM node:alpine AS builder
ARG PROXY=http://myproxy
ARG NOPROXY=localhost,127.0.0.1
ENV http_proxy=${PROXY}
ENV https_proxy=${PROXY}
ENV NO_PROXY=${NOPROXY}
ENV no_proxy=${NOPROXY}
WORKDIR /app
COPY . .
RUN npm install && \
npm run build
FROM nginx:alpine
COPY --from=builder /app/dist/* /usr/share/nginx/html/
我使用以下容器构建容器
docker build -t form_angular:v1
并使用
运行它docker run -d -p8088:80 form_angular:v1
REST Api的第二个Dockerfile
看起来像这样:
FROM continuumio/miniconda3
ARG PROXY=http://myproxy
ARG NOPROXY=localhost,127.0.0.1
ENV http_proxy=${PROXY}
ENV https_proxy=${PROXY}
ENV NO_PROXY=${NOPROXY}
ENV no_proxy=${NOPROXY}
COPY my_environment.yml my_environment.yml
SHELL ["/bin/bash", "-c"]
RUN echo "Using proxy $PROXY" \
&& touch /etc/apt/apt.conf \
&& echo "Acquire::http::Proxy \"$PROXY\";" >> /etc/apt/apt.conf \
&& cat /etc/apt/apt.conf \
&& apt-get -q -y update \
&& DEBIAN_FRONTEND=noninteractive apt-get -q -y upgrade \
&& apt-get -q -y install \
build-essential \
&& apt-get -q clean \
&& rm -rf /var/lib/apt/lists/*
RUN ["conda", "env", "create", "-f", "my_environment.yml"]
COPY user_feedback.py user_feedback.py
CMD source activate my_environment; gunicorn -b 0.0.0.0:3000 user_feedback:app
建筑物:
docker build -t form_rest:latest .
运行:
docker run --name form_rest -d -p 3000:3000
正如我所说,在localhost
上运行时,所有功能都可以按预期运行。现在如何使这两个容器相互通信以进行“全局”部署?
答案 0 :(得分:1)
您的baseURL被硬编码为localhost。对于“全局”部署,您需要更改baseURL以指向REST api的全局端点。这将需要您知道全局端点,并且它必须是静态的。
另一种选择是将prod的baseURL设置为/ api,并将有角的nginx配置为将/ api代理到您的REST api。您需要链接容器才能正常工作,但不需要在REST api容器上公开公共端口,只需通过nginx代理它即可。
我在项目中使用nginx代理选项,并使用docker-compose处理所有链接和容器间通信。
docker-compose.yml和nginx.conf文件示例。取自我目前正在使用的东西,认为它应该对您有用。
docker-compose.yml
version: '3.4'
services:
nginx:
container_name: nginx
image: form_angular
build:
context: .
dockerfile: <path to angular/nginx dockerfile>
ports:
- 8088:80
networks:
- my-network
restapi:
container_name: restapi
image: form_rest
build:
context: .
dockerfile: <path to rest dockerfile>
networks:
- my-network
networks:
my-network:
driver: bridge
nginx.conf:
events {
worker_connections 1024;
}
http {
upstream api {
server restapi:3000;
}
server {
server_name nginx;
root /usr/share/nginx/html;
index index.html;
include /etc/nginx/mime.types;
location /api/ {
proxy_pass http://api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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-NginX-Proxy true;
proxy_cache_bypass $http_upgrade;
}
location /assets/ {
access_log off;
expires 1d;
}
location ~ \.(css|js|svg|ico)$ {
access_log off;
expires 1d;
}
location / {
try_files $uri /index.html;
}
}
}
答案 1 :(得分:0)
在容器中使用localhost时,表示容器本身,而不是运行容器的主机。 因此,如果您从第二个容器(在您的情况下为UI)指向“ localhost”,则该新容器将查看自身,而找不到API。
解决问题的一种方法是使容器按名称可达。
在您的情况下,最简单的方法是使用docker-compose: 例如:
version: '3'
services:
angular:
image: "form_angular:v1"
container_name: "form_angular"
ports:
- "8088:80"
external_links:
- restapi
restapi:
image: "form_rest:latest"
container_name: "form_rest"
ports:
- "3000:3000"
external_links:
- angular
因此,您可以使用名称(作为DNS)restapi
和angular
来从restapi到达restapi。
我建议您在https://docs.docker.com/compose/
阅读更多有关docker-compose的信息。它非常通用且容易,您可以使用它很长时间,直到您决定构建自己的云;)