SCM-Manager Docker behind Reverse Proxy (Traefik)

I’ve been trying this weekend to get the Docker Version of the SCM-Manager running behind Traefik Reverse Proxy. I dunno if some of you have already tried the same thing.

This is the content of the compose-file:

Version: '3.3'
services:
  scm:
    image: scmmanager/scm-manager:2.39.0
   # ports:
    # - "8081:8080"
     # if the ssh plugin is used
     # - "2222:2222"
    volumes:
     - ./scmhome:/var/lib/scm:rw
     - ./certs/cacerts:/opt/java/openjdk/lib/security/cacerts:rw
    networks:
     - aqua_services
     - default
    environment:
     - JAVA_OPTS=-DproxySet=true -Dhttp.proxyHost=172.20.0.2 -Dhttps.proxyPort=8080
    labels:
     - traefik.enable=true"
     - "traefik.http.routers.scmmanager.rule=PathPrefix(`/scm`)"
     - "traefik.http.middlewares.scmmanager-prefix.stripprefix.prefixes=/scm"
     - "traefik.http.routers.scmmanager.middlewares=scmmanager-prefix@docker"
     - "traefik.http.routers.scmmanager.entrypoints=web-secure"
     - "traefik.http.services.scmmanager.loadbalancer.server.port=8080"
     - "traefik.http.services.scmmanager.loadbalancer.server.scheme=http"
     - "traefik.http.routers.scmmanager.tls=true"

networks:
  aqua_services:
    external: true
  default:
    driver: bridge

A small extract from the log:

2022-11-07 08:18:45.762 [qtp1943325854-14] [3lTMUH7li6] WARN  sonia.scm.security.DefaultAccessTokenCookieIssuer - issuet a non secure cookie, protect your scm-manager instance with tls https://scm-manager.org/docs/latest/en/administration/scm-server/
2022-11-07 08:19:16.397 [qtp1943325854-12] [DQTMUHFjp7] WARN  sonia.scm.security.DefaultAccessTokenCookieIssuer - issuet a non secure cookie, protect your scm-manager instance with tls https://scm-manager.org/docs/latest/en/administration/scm-server/
2022-11-07 08:19:47.045 [qtp1943325854-18] [4bTMUHNi98] WARN  sonia.scm.security.DefaultAccessTokenCookieIssuer - issuet a non secure cookie, protect your scm-manager instance with tls https://scm-manager.org/docs/latest/en/administration/scm-server/
2022-11-07 08:20:17.617 [qtp1943325854-14] [76TMUHVfF9] WARN  sonia.scm.security.DefaultAccessTokenCookieIssuer - issuet a non secure cookie, protect your scm-manager instance with tls https://scm-manager.org/docs/latest/en/administration/scm-server/
2022-11-07 08:20:54.255:INFO::main: Logging initialized @274ms to org.eclipse.jetty.util.log.StdErrLog
2022-11-07 08:20:54.570:INFO:oejs.Server:main: jetty-9.4.44.v20210927; built: 2021-09-27T23:02:44.612Z; git: 8da83308eeca865e495e53ef315a249d63ba9332; jvm 11.0.16.1+1-alpine-r0
2022-11-07 08:20:55.729:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /scm, did not find org.eclipse.jetty.jsp.JettyJspServlet
2022-11-07 08:20:55.749:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2022-11-07 08:20:55.749:INFO:oejs.session:main: No SessionScavenger set, using defaults
2022-11-07 08:20:55.752:INFO:oejs.session:main: node0 Scavenging every 660000ms
2022-11-07 08:20:56.005 [main] [          ] INFO  sonia.scm.lifecycle.classloading.ClassLoaderLifeCycle - create new simple ClassLoaderLifeCycle
2022-11-07 08:20:56.013 [main] [          ] INFO  sonia.scm.lifecycle.BootstrapContextFilter - register for restart events
2022-11-07 08:20:56.015 [main] [          ] INFO  sonia.scm.event.LegmanScmEventBus - create new event bus ScmEventBus-1
2022-11-07 08:20:56.097 [main] [          ] WARN  io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics - Failed to bind as org.apache.shiro.concurrent.SubjectAwareExecutorService is unsupported.
2022-11-07 08:20:56.099 [main] [          ] INFO  sonia.scm.event.ScmEventBus - use sonia.scm.event.LegmanScmEventBus as event bus implementation
2022-11-07 08:20:56.169 [main] [          ] INFO  sonia.scm.lifecycle.BootstrapContextListener - start scm-manager initialization
2022-11-07 08:20:56.673 [main] [          ] INFO  sonia.scm.plugin.PluginProcessor - collect plugins
2022-11-07 08:20:56.702 [main] [          ] INFO  sonia.scm.plugin.PluginProcessor - install plugin tree:
+- scm-cas-plugin@2.4.0
+- scm-git-plugin@2.39.0
+- scm-legacy-plugin@2.39.0
+- scm-hg-plugin@2.39.0
+- scm-svn-plugin@2.39.0
2022-11-07 08:20:57.179 [main] [          ] INFO  sonia.scm.update.repository.XmlRepositoryV1UpdateStep - no v1 repositories database file found
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.autoconfig.AutoConfigModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class com.cloudogu.scm.cas.config.ConfigurationModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.security.gpg.GPGModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.web.SvnServletModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.web.GitServletModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.legacy.LegacyModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.web.HgServletModule
2022-11-07 08:20:57.391 [main] [          ] INFO  sonia.scm.lifecycle.modules.ApplicationModuleProvider - add module class sonia.scm.repository.hooks.HookModule
2022-11-07 08:20:57.425 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.metrics.HttpMetricsFilter to filter chain
2022-11-07 08:20:57.425 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.filter.BaseUrlFilter to filter chain
2022-11-07 08:20:57.425 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.security.TokenExpiredFilter to filter chain
2022-11-07 08:20:57.425 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.web.filter.DefaultHttpProtocolServletAuthenticationFilter to filter chain
2022-11-07 08:20:57.425 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class com.cloudogu.scm.cas.browser.CasAuthenticationFilter to filter chain
2022-11-07 08:20:57.426 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.web.security.ApiAuthenticationFilter to filter chain
2022-11-07 08:20:57.427 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.legacy.LegacyProtocolServletAuthenticationFilter to filter chain
2022-11-07 08:20:57.427 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class com.cloudogu.scm.cas.browser.ForceCasLoginFilter to filter chain
2022-11-07 08:20:57.427 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.filter.MDCFilter to filter chain
2022-11-07 08:20:57.427 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind filter class sonia.scm.web.security.TokenRefreshFilter to filter chain
2022-11-07 08:20:57.428 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind servlet class sonia.scm.lifecycle.RestartServlet to servlet chain
2022-11-07 08:20:57.428 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind servlet class sonia.scm.web.protocol.HttpProtocolServlet to servlet chain
2022-11-07 08:20:57.428 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind servlet class sonia.scm.web.i18n.I18nServlet to servlet chain
2022-11-07 08:20:57.429 [main] [          ] INFO  sonia.scm.filter.WebElementModule - bind servlet class sonia.scm.WebResourceServlet to servlet chain
2022-11-07 08:20:57.451 [main] [          ] INFO  sonia.scm.plugin.DefaultExtensionProcessor - start processing extensions
2022-11-07 08:20:57.456 [main] [          ] WARN  sonia.scm.plugin.ExtensionBinder - could not find extension for extension point interface sonia.scm.io.FileSystem
2022-11-07 08:20:57.499 [main] [          ] INFO  sonia.scm.plugin.DefaultExtensionProcessor - bound extensions in 47.55 ms
2022-11-07 08:20:57.578 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class com.cloudogu.scm.cas.rest.CasRestRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class com.cloudogu.scm.cas.browser.CasTokenRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.security.AnonymousRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.legacy.LegacyRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.security.DefaultRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.initialization.InitializationRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.security.ApiKeyRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.web.security.AdministrationContextRealm
2022-11-07 08:20:57.579 [main] [          ] INFO  sonia.scm.lifecycle.modules.ScmSecurityModule - bind security realm class sonia.scm.security.BearerRealm
Nov 07, 2022 8:20:58 AM com.google.inject.servlet.GuiceFilter setPipeline
WARNING: Multiple Servlet injectors detected. This is a warning indicating that you have more than one GuiceFilter running in your web application. If this is deliberate, you may safely ignore this message. If this is NOT deliberate however, your application may not work as expected.
2022-11-07 08:20:58.491 [main] [          ] WARN  sonia.scm.cache.GuavaCacheConfigurationReader - could not find manual configuration at /var/lib/scm/ext/gcache.xml
2022-11-07 08:20:58.925 [main] [          ] INFO  sonia.scm.repository.DefaultRepositoryManager - added RepositoryHandler class sonia.scm.repository.GitRepositoryHandler for type Type{name=git, displayName=Git}
2022-11-07 08:20:58.925 [main] [          ] INFO  sonia.scm.repository.DefaultRepositoryManager - added RepositoryHandler class sonia.scm.repository.HgRepositoryHandler for type Type{name=hg, displayName=Mercurial}
2022-11-07 08:20:59.078 [main] [          ] INFO  sonia.scm.repository.DefaultRepositoryManager - added RepositoryHandler class sonia.scm.repository.SvnRepositoryHandler for type Type{name=svn, displayName=Subversion}
2022-11-07 08:20:59.172 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.plugin.PluginCenterRefresh
2022-11-07 08:20:59.173 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.api.v2.resources.GitRepositoryConfigChangeClearRepositoryCacheListener
2022-11-07 08:20:59.173 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.spi.FileLockPreCommitHook
2022-11-07 08:20:59.173 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.initialization.DefaultInitializationFinisher
2022-11-07 08:20:59.186 [main] [          ] INFO  sonia.scm.web.security.AdministrationContextRealm - assign admin permissions to admin context user _scmsystem
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.update.RepositoryUpdateAfterCreationHook
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.RemoveDeletedRepositoryRole
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.DefaultRepositoryRoleManager
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.DefaultBranchDeleteProtection
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.config.ScmConfigurationChangedListener
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.LastModifiedUpdateListener
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.ReadOnlyCheckInitializer
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.DefaultBranchChangedDispatcher
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.security.AuthorizationChangedEventProducer
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.user.AnonymousUserDeletionEventHandler
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.EventDrivenRepositoryArchiveCheckInitializer
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.repository.GitRepositoryModifyListener
2022-11-07 08:20:59.200 [main] [          ] INFO  sonia.scm.lifecycle.modules.EagerSingletonModule - initialize eager singleton sonia.scm.user.DefaultUserManager
2022-11-07 08:20:59.303 [main] [          ] INFO  sonia.scm.repository.work.WorkdirProvider - deleting 0 old work dirs in /tmp/scm-work
2022-11-07 08:20:59.315:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@ec5f944{SCM-Manager ${project.version},/scm,file:///var/cache/scm/work/webapp/webapp/,AVAILABLE}{./var/webapp/scm-webapp.war}
2022-11-07 08:20:59.320:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2022-11-07 08:20:59.321:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@9205c0a{/,[file:///opt/scm-server/var/webapp/docroot/],AVAILABLE}
2022-11-07 08:20:59.341:INFO:oejs.AbstractConnector:main: Started ServerConnector@4b44655e{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2022-11-07 08:20:59.342:INFO:oejs.Server:main: Started @5371ms
 

Maybe someone knows a way around it or to fix it somehow. I will try to get it to work in the meantime and post the solution, if I’m able to find it :slight_smile:

Thanks

1 Like

Hi @araiguma90

welcome to our community!

It looks like that there is missing a " in your compose file:

labels:
- traefik.enable=true"

Could you fix that and try again?

Hello @christoph.loose, thank you for welcoming me.

Thanks for the tip, but unfortunately it does not work either.
Are there specific parameters (like docker environment variables) or settings inside the scm-manager dashboard that need to be modified in order to get it to work behind a reverse proxy?

Thanks in advance

Hey @araiguma90 ,

the log excerpt tells me that SCM-Manager is up and running. So I’m not sure, what the error looks like. Can you elaborate this part a bit more? SCM-Manager does not need a special configuration for reverse proxies, only the proxy has to set some headers (X-Forwarded-...) and may have to handle paths correctly. If even the login or the startup wizard shows up, you should take a look at the reverse proxy settings. I don’t know much about Traefik, though.

Hello @pfeuffer.

I’ve now added the X-Forwarded-Host, X-Forwarded-For and X-Forwarded-Proto to the Compose-File.

Unfortunately I’m now getting Bad Gateway.
Do I have to edit the Base-Url inside of SCM-Manager to the later used URL, for it to work properly?

I need also to figure out how to get the following settings inside the docker-compose label for traefik:

# assuming scm-manager is running on localhost at port 8080
location /scm {
    proxy_pass http://scm:8080;
}

Thank You :slight_smile:

Ok. Now I’m getting the “SCM-Server” Headline on the Tab of the Browser.

But it looks like the Site is constantly reloading.
I guess there is something happening in the background with some faulty redirections or similar.

Okay. It works now.

This is the used docker-compose config I ended up with:

version: '2.0'
services:
  scm:
    image: scmmanager/scm-manager:2.39.0
    # No open Ports since the container is managed by traefik
    #ports:
    #- "8081:8080"
    # if the ssh plugin is used
    # - "2222:2222"
    volumes:
    - ./data/scmhome:/var/lib/scm:rw
    - ./certs/cacerts:/opt/java/openjdk/lib/security/cacerts:rw
    networks:
     # The Network "proxy_services" is the traefik network
     - proxy_services
     - default
    environment:
     - TZ="Europe/Berlin"
    labels:
     - "traefik.enable=true"
     - "traefik.http.routers.scmmanager.rule=PathPrefix(`/scm`)"
     #- "traefik.http.middlewares.scmmanager-prefix.stripprefix.prefixes=/scm"
     #- "traefik.http.routers.scmmanager.middlewares=scmmanager-prefix@docker"
     - "traefik.http.routers.scmmanager.entrypoints=web-secure"
     - "traefik.http.middlewares.scmHeaders.headers.customrequestheaders.X-Forwarded-For=DNS.NAME"
     - "traefik.http.middlewares.scmHeaders.headers.customrequestheaders.X-Forwarded-Proto=https"
     - "traefik.http.middlewares.scmHeaders.headers.customrequestheaders.X-Forwarded-Host=DNS.NAME"
     - "traefik.http.services.scmmanager.loadbalancer.server.port=8080"
     - "traefik.http.services.scmmanager.loadbalancer.server.scheme=http"
     - "traefik.http.routers.scmmanager.tls=true"

networks:
  proxy_services:
    external: true
  default:
    driver: bridge

If anyone stumbles upon this thread in the future, I hope this helps you saving some time :slight_smile:

Hey @araiguma90 , thanks for this great update! Glad you made it.