diff --git a/README.md b/README.md
index 7ae751e20898483a490e9558ac68d260f081ebc7..d007e8d5384dbd4de04f9cd0e107971cd1e3ca92 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,16 @@ gitlab-workhorse can listen on either a TCP or a Unix domain socket. It
 can also open a second listening TCP listening socket with the Go
 [net/http/pprof profiler server](http://golang.org/pkg/net/http/pprof/).
 
+### Relative URL support
+
+If you are mounting GitLab at a relative URL, e.g.
+`example.com/gitlab`, then you should also use this relative URL in
+the `authBackend` setting:
+
+```
+gitlab-workhorse -authBackend http://localhost:8080/gitlab
+```
+
 ## Installation
 
 To install into `/usr/local/bin` run `make install`.
diff --git a/authorization.go b/authorization.go
index c12ac90118d3710e0ebe569cb120531b566c4d1b..4f58a6d270150649666fdf0effd8aa930cb3515d 100644
--- a/authorization.go
+++ b/authorization.go
@@ -9,7 +9,7 @@ import (
 )
 
 func (u *upstream) newUpstreamRequest(r *http.Request, body io.Reader, suffix string) (*http.Request, error) {
-	url := u.authBackend + r.URL.RequestURI() + suffix
+	url := u.authBackend + "/" + strings.TrimPrefix(r.URL.RequestURI(), u.relativeURLRoot) + suffix
 	authReq, err := http.NewRequest(r.Method, url, body)
 	if err != nil {
 		return nil, err
diff --git a/main.go b/main.go
index 0c5a9fcb2d4b5816b2149a8ea97a8ea7ff4acced..324e4dc113480552bb45f1cf6bbcc1940f373f32 100644
--- a/main.go
+++ b/main.go
@@ -36,7 +36,6 @@ var listenUmask = flag.Int("listenUmask", 022, "Umask for Unix socket, default:
 var authBackend = flag.String("authBackend", "http://localhost:8080", "Authentication/authorization backend")
 var authSocket = flag.String("authSocket", "", "Optional: Unix domain socket to dial authBackend at")
 var pprofListenAddr = flag.String("pprofListenAddr", "", "pprof listening address, e.g. 'localhost:6060'")
-var relativeURLRoot = flag.String("relativeURLRoot", "/", "GitLab relative URL root")
 var documentRoot = flag.String("documentRoot", "public", "Path to static files content")
 var responseHeadersTimeout = flag.Duration("proxyHeadersTimeout", time.Minute, "How long to wait for response headers when proxying the request")
 var developmentMode = flag.Bool("developmentMode", false, "Allow to serve assets from Rails app")
@@ -170,6 +169,5 @@ func main() {
 	}
 
 	upstream := newUpstream(*authBackend, proxyTransport)
-	upstream.SetRelativeURLRoot(*relativeURLRoot)
 	log.Fatal(http.Serve(listener, upstream))
 }
diff --git a/upstream.go b/upstream.go
index b6ac589714f675b5057cfc62830f94445c7b337e..bcfbc8a34461e4a698b80cde4bb18db745dc654c 100644
--- a/upstream.go
+++ b/upstream.go
@@ -64,29 +64,30 @@ type gitRequest struct {
 }
 
 func newUpstream(authBackend string, authTransport http.RoundTripper) *upstream {
-	u, err := url.Parse(authBackend)
+	gitlabURL, err := url.Parse(authBackend)
 	if err != nil {
 		log.Fatalln(err)
 	}
+	relativeURLRoot := gitlabURL.Path
+	if !strings.HasSuffix(relativeURLRoot, "/") {
+		relativeURLRoot += "/"
+	}
+
+	// If the relative URL is '/foobar' and we tell httputil.ReverseProxy to proxy
+	// to 'http://example.com/foobar' then we get a redirect loop, so we clear the
+	// Path field here.
+	gitlabURL.Path = ""
 
 	up := &upstream{
 		authBackend:     authBackend,
 		httpClient:      &http.Client{Transport: authTransport},
-		httpProxy:       httputil.NewSingleHostReverseProxy(u),
-		relativeURLRoot: "/",
+		httpProxy:       httputil.NewSingleHostReverseProxy(gitlabURL),
+		relativeURLRoot: relativeURLRoot,
 	}
 	up.httpProxy.Transport = authTransport
 	return up
 }
 
-func (u *upstream) SetRelativeURLRoot(relativeURLRoot string) {
-	u.relativeURLRoot = relativeURLRoot
-
-	if !strings.HasSuffix(u.relativeURLRoot, "/") {
-		u.relativeURLRoot += "/"
-	}
-}
-
 func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
 	var g httpRoute
 
@@ -107,7 +108,7 @@ func (u *upstream) ServeHTTP(ow http.ResponseWriter, r *http.Request) {
 
 	// Check URL Root
 	URIPath := cleanURIPath(r.URL.Path)
-	if !strings.HasPrefix(URIPath, u.relativeURLRoot) {
+	if !strings.HasPrefix(URIPath, u.relativeURLRoot) && URIPath+"/" != u.relativeURLRoot {
 		httpError(&w, r, fmt.Sprintf("Not found %q", URIPath), http.StatusNotFound)
 		return
 	}