首页 \ 问答 \ 在Traefik中是否有与ReverseProxyPass相同的Apache?(Is there an equivalent to ReverseProxyPass for Apache in Traefik?)

在Traefik中是否有与ReverseProxyPass相同的Apache?(Is there an equivalent to ReverseProxyPass for Apache in Traefik?)

我已经设置Traefik在Docker Swarm模式下工作。 我使用以下命令将Portainer部署到集群中:

docker service create                            \
                                                 \
   --label "traefik.port=9000"                   \
   --label "traefik.docker.network =traefik-net" \
   --label "traefik.frontend.rule=Host:`hostname -f`;PathPrefixStrip:/portainer" \
   --label="traefik.backend=portainer" \
                                       \
   --network traefik-net               \
   --constraint "node.role == manager" \
   -p 9000:9000                        \
   --mount "type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock" \
   --name portainer \
   portainer/portainer

可以看出,我已经通过使用标签将Traefik配置为将/portainer portainer的请求代理到Portainer服务。 但是,Protainer提供的链接来自/因为它不知道它被代理,因此应用程序不起作用,因为Traefik不知道如何路由每个链接。

我试图避免不得不改变服务的部署以与Traefik一起工作,因为我希望它是透明的。 为此,有可能让Traefik重写来自服务的链接,如ReverseProxyPass for Apache吗?

我知道Traefik现在设置了X-Forwarded-Prefix但我不确定如何使用Portainer之类的东西来开箱即用,或者实际上是从Docker Store安装的其他服务。


I have setup Traefik to work in Docker Swarm mode. I have deployed Portainer into the cluster with the following command:

docker service create                            \
                                                 \
   --label "traefik.port=9000"                   \
   --label "traefik.docker.network =traefik-net" \
   --label "traefik.frontend.rule=Host:`hostname -f`;PathPrefixStrip:/portainer" \
   --label="traefik.backend=portainer" \
                                       \
   --network traefik-net               \
   --constraint "node.role == manager" \
   -p 9000:9000                        \
   --mount "type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock" \
   --name portainer \
   portainer/portainer

As can be seen I have configured Traefik, through the use of labels, to proxy the request for /portainer to the Portainer service. However the links that are served by Protainer are from / as it does not know it is being proxied, so the application does not work as Traefik does not know how to route each link.

I am trying to avoid having to change the deployments of services to work with Traefik as I want it to be transparent. To that end is it possible to get Traefik to rewrite the links from the service like ReverseProxyPass for Apache does?

I know that Traefik now sets the X-Forwarded-Prefix but I am not sure how to get things like Portainer to use it out of the box or indeed other services that are installed from the Docker Store for example.


原文:https://stackoverflow.com/questions/44246098
更新时间:2023-04-10 11:04

最满意答案

ApplyAB类没有功能依赖,因此当GHC尝试选择实例时,输入类型不确定结果类型。 在这种情况下,这会导致hFoldr链中的所有中间类型变得模糊,并且GHC不知道要选择哪些实例。

要解决这个问题,你可以使用一个技巧,在结果类型中将结果类型完全保持在实例的头部,并 GHC选择实例使用等式约束来限制它(只有实例的头部用于选择)。

如果你这样做:i ApplyAB在GHCi中使用:i ApplyAB ,你会注意到一些预定义的实例使用了这样的等式约束。

使用它(并添加TypeFamilies )使您的代码适合我:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Lib
    ( y
    ) where

import Data.HList

data HConcat2 = HConcat2
instance s ~ String => ApplyAB HConcat2 (String, String) s where
  applyAB _ (a,b) = a ++ b
instance s ~ String => ApplyAB HConcat2 (Int, String) s where
  applyAB _ (_,a) = a

x :: HList '[Int, String, Int, String]
x = 3 .*. "Hello" .*. 4 .*. " World" .*. HNil

y :: String
y = hFoldr HConcat2 "Result: " x

There is no functional dependency on the ApplyAB class, so when GHC tries to select an instance, the input types don't determine the result type. In this case, this causes all the intermediate types in the hFoldr chain to become ambiguous, and GHC doesn't know which instances to select.

To solve this, you can use a trick, where you keep the result type completely general in the head of the instance, and use an equational ~ constraint to restrict it after GHC has selected the instance (only the head of an instance is used for selection).

If you do :i ApplyAB in GHCi, you will notice that several of the pre-defined instances use such equational constraints.

Using this (and adding TypeFamilies) makes your code work for me:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Lib
    ( y
    ) where

import Data.HList

data HConcat2 = HConcat2
instance s ~ String => ApplyAB HConcat2 (String, String) s where
  applyAB _ (a,b) = a ++ b
instance s ~ String => ApplyAB HConcat2 (Int, String) s where
  applyAB _ (_,a) = a

x :: HList '[Int, String, Int, String]
x = 3 .*. "Hello" .*. 4 .*. " World" .*. HNil

y :: String
y = hFoldr HConcat2 "Result: " x

相关问答

更多
  • 几点: 1)首选模块功能属性和方法。 List.map (fun x -> x.Length) ["hello"; "world"] // fails List.map String.length ["hello"; "world"] // works let mapFirst xss = Array.map (fun xs -> xs.[0]) xss // fails let mapFirst xss = Array.map (fun xs -> Array.get xs 0) xss // work ...
  • 当没有类型签名绑定时, f2具有多态推断类型( Fractional a => a ),由于单态限制(除非禁用),因此必须单态化。 在没有其他默认声明的情况下,具有Fractional约束的类型变量默认为Double 。 Hugs似乎首先进行默认操作,然后阻止尝试将声明的Float f1绑定到Double值f2 。 GHC看起来更进一步,并且看到f2用于Float类型,因此单态f2到Float 。 我不确定语言标准在这种情况下要求的行为,但我认为GHC是正确的,因为单态化只应在键入一个绑定组后发生,我认为f ...
  • 其他人已经介绍了为什么它会生成相同的代码 所以,要回答真正的问题 - 简短的回答是更喜欢这个: ArrayList strings = new ArrayList<>(); 因为它比这更简短,同时传达了相同的含义(对人类和编译器): ArrayList strings = new ArrayList(); 但是避免不必要地引起这样的警告: ArrayList strings = new ArrayList(); 至于简短 ...
  • ApplyAB类没有功能依赖,因此当GHC尝试选择实例时,输入类型不确定结果类型。 在这种情况下,这会导致hFoldr链中的所有中间类型变得模糊,并且GHC不知道要选择哪些实例。 要解决这个问题,你可以使用一个技巧,在结果类型中将结果类型完全保持在实例的头部,并在 GHC选择实例后使用等式约束来限制它(只有实例的头部用于选择)。 如果你这样做:i ApplyAB在GHCi中使用:i ApplyAB ,你会注意到一些预定义的实例使用了这样的等式约束。 使用它(并添加TypeFamilies )使您的代码适合我 ...
  • 这很简单,可以理解吗? def doSomething(a, b){ a + b } //Type inferred to String assert "HelloWorld" == doSomething('Hello','World') assert "String" == doSomething('Hello','World').class.simpleName //Type inferred to Integer assert 5 == doSomething(2,3) assert "I ...
  • 你可以使用Zip (或在这种情况下为Zip.Aux )类型的类Zip.Aux所有东西封装在一个方法中: import shapeless._, shapeless.ops.hlist._ object mix extends Poly1 { implicit def caseTuple[T] = at[(T, T)](t => if (util.Random.nextBoolean) t._2 else t._1) } def zipAndMix[L <: HList, Z <: HList ...
  • 这完全不依赖订单。 参数p => p.Age添加约束,无论TValue是否必须是可以存储int的类型。 这可以是int或它继承的任何类型,例如object 。 当你age超过时,你说TValue必须是可以存储object的类型。 然后,它会选择满足所有这些约束的派生类型,在这种情况下,它是object 。 如果更改参数的顺序,也会发生同样的情况。 It's not order dependant at all. The parameter p => p.Age is adding the constrain ...
  • 对于自定义类型类,这不是太糟糕。 请注意,在某种意义上,我们需要两个“基本情况” - 一个启动顶级HList ,一个启动每个单独的内部HList 。 然后,归纳步骤显示如何将新项目(我们知道如何从输入中提取)添加到我们添加的最后一个HList 。 import shapeless._, ops.hlist.Selector trait Picker[I <: HList, O <: HList] { def apply(i: I): O } object Picker { implicit de ...
  • 你非常接近,但是choose的定义有点错误: map使用Poly1而不是Poly2 。 你正在映射一个元组的列表,所以你需要一个带有单个参数(一个元组)的多态函数。 你提供的是一个带有两个参数的多态函数。 差异很微妙,但它就在那里。 这是一个有效的版本: import shapeless.{ HNil, Poly1 } object choose extends Poly1 { implicit def caseInt = at[(Int,Int)]{ case (_,n) if ...
  • 错误文本包含解决方案 import shapeless.ops.hlist.Mapper def mapOverHlist[L <: HList](list: L)(implicit m: Mapper[id.type, L]): m.Out = list.map(id) 方法map接受隐式参数,您应该提供此类参数(通过向方法声明添加相同的参数)。 Error text contains solution: import shapeless.ops.hlist.Mapper def mapOver ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。