当前,我正在尝试设置一个简单的Web服务。为此,我使用了phyton3 http.server类。整个过程都在Docker容器中运行(称为simple_webservice;暴露端口8010)。
运行没有traefik的容器时,我可以通过调用http://localhost:8010
来访问网站。
我用于实现网络服务器的代码可以在here中找到:
import http.server
import socketserver
PORT = 8010
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
泊坞窗文件也很简单(代理用于通过apt-get下载):
FROM ubuntu:latest
ENV http_proxy 'http://proxy:port'
ENV https_proxy 'http://proxy:port'
ENV no_proxy 'company.net'
RUN apt-get update && apt-get install -y \
build-essential \
python3
RUN mkdir /www
COPY ext/ /www
ADD ./entrypoint.sh /entrypoint.sh
ADD server.py /www/server.py
RUN chmod +x /entrypoint.sh
ENTRYPOINT [ "./entrypoint.sh"]
这是我的docker-compose.yml文件,用于将我的容器与traefik反向代理一起使用:
version: '3'
services:
simple_webservice:
build: .
image: "simple_webservice"
expose:
- 8010
networks:
- internal_network
- default
labels:
- traefik.passHostHeader=true
- traefik.docker.network=internal_network
- traefik.enable=true
- traefik.backend=simple_webservice
- traefik.frontend.rule=PathPrefix:/webservice
- traefik.port=8010
networks:
internal_network:
external: true
现在,通过调用http://localhost/webservice
访问相同的Web服务时,它总是返回:
错误响应
错误代码:404
消息:找不到文件。
错误代码说明:HTTPStatus.NOT_FOUND-没有与给定URI匹配的内容
所以我认为我的服务仍然可以访问并且traefik正常运行,但是我的网络服务器无法处理路径前缀 / webservice ? 我该如何解决?
编辑: 通过发布解决方法来回答。
答案 0 :(得分:0)
如果/webservice
仅在前端公开,则可以使用the stripprefix
middleware in Traefik删除它。请注意,这可能会中断绝对中断,并且会导致应用程序中的某些相对重定向和链接(即/foo
将不再指向您的前端服务的端点)。
# Strip prefix /foobar and /fiibar
labels:
- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar, /fiibar"
您可以根据需要使用X-Forwarded-Prefix
标头为这些路径添加前缀。
可以查询X-Forwarded-Prefix标头来动态构建此类URL。
但是,我的建议是通常将您的WSGI应用程序(通常在Python中最终使用)安装在多个端点中,以便在必要时与其自己的URL建立适当的关系。这样,大多数事情都可以同时使用前缀和不使用前缀(直接访问时)。如何执行将取决于所使用的框架。
答案 1 :(得分:0)
我找到了解决此问题的方法。但是,这不是一般的解决方案。 (正如我的Dockerfile所说,我在 / www / 中进行操作。)
背景
(重新)加载网页时,将调用do_GET()
方法,该方法将调用send_head()
现在,send_head()
中有一个可变路径;使用traefik时,变量path
(在第66行分配)
path = self.translate_path(self.path)
在我的情况下存储 / www / webservice ,这不是有效路径(仅 / www / 是有效的。)
(不良)解决方案
所以,我的解决方法是通过简单地添加以下行来删除 / www /...之后的内容
path = path.replace('/webservice', '')
。现在,我的路径再次有效。
请注意,这只是一种解决方法。我猜有一种更可行的方法,无需更改SimpleHTTPServer.py
源文件,但我还没有找到一种方法。
send_head(self)方法如下所示:
def send_head(self):
path = self.translate_path(self.path)
path = path.replace('/webservice', '')
f = None
if os.path.isdir(path):
parts = urllib.parse.urlsplit(self.path)
[...]
我也希望能为我的问题提供一个更通用的解决方案。