Spring Boot在Eclipse中工作,但在Docker中不工作。

huangapple 未分类评论49阅读模式
英文:

Spring boot works in Eclipse, not in docker

问题

我一直在使用Docker Compose构建一个小的Spring Boot应用程序。我有一个包含Web应用程序的容器和一个包含数据库的容器。为了开发和调试,我一直在使用Docker Compose启动数据库容器,并在Eclipse中以调试模式运行Spring Boot应用程序。到目前为止,一切都很顺利。

然后,我尝试使用Docker Compose运行整个应用程序。以下是我的YAML文件和日志输出(为了测试Docker部分,我映射了JAR文件,而不是每次重新构建Docker镜像):

version: '3'

services:

    myapp-service:
        image: myapp-service
        env_file: 
           - common.env
        ports:
           - 8080:8080
        volumes:
           - "./target/myapp-service.jar:/myapp-service.jar"
        depends_on: 
           - database

    database:
        image: mongo
        env_file:
           - common.env
        volumes:
           - "./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro"
        ports:
           - "27017-27019:27017-27019"

我有一个自定义的登录表单,在Eclipse中运行时可以正常工作。当我尝试在Docker中运行整个应用程序并导航到网页时,出现以下日志:

...(日志部分省略)...
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/views/login.jsp

在Docker容器中运行应用程序时,您可能会遇到Spring Security配置或Docker网络配置方面的问题。这种情况下,可能会有一些步骤可以尝试解决问题:

  1. 数据库连接配置: 确保数据库连接配置正确。您提到在Docker中使用database作为主机名,但在Eclipse中使用localhost。这可能导致数据库连接问题。在Docker容器中,使用服务名称作为主机名是正确的做法,但是要确保Spring Boot应用程序的数据库连接配置也正确。

  2. Docker网络: 默认情况下,Docker Compose会创建一个自定义的网络以供所有服务之间进行通信。确保您的应用程序配置正确地连接到这个网络。如果您在Docker Compose文件中没有明确指定网络,那么所有的服务应该在同一个默认网络中。

  3. Spring Security配置: 根据日志,似乎是Spring Security拦截了请求并返回了404错误。确保您的Spring Security配置在Docker环境中正确地工作。可能需要检查过滤器链、URL模式、角色授权等配置。

  4. 路径和文件映射: 确保JAR文件和其他资源正确地映射到Docker容器中。您在Docker Compose文件中的volumes部分似乎是正确的,但要确保文件路径和容器中的路径对应正确。

  5. 依赖项: 确保myapp-service服务在数据库服务之后启动。根据您的配置,myapp-service可能依赖于数据库服务的可用性。

根据您提供的信息,您可能需要逐一检查这些方面,以便确定问题的根本原因并解决它。如果您的应用程序在Docker容器外正常工作,但在容器内出现问题,可能是环境变量、配置或网络方面的问题。

英文:

I've been working on a little spring boot app using docker-compose. I've got a container with the web app and one with the database. For development/debugging I've been launching just the database container using docker-compose and running the spring boot app in debug mode in Eclipse. So far, so good.

Then I try to run the whole thing using docker-compose. This is my yml file and log output below (some names have been changed to protect the innocent)...for testing the docker part I've mapped the jar file rather than rebuild the docker image every time.

version: '3'

services:

    myapp-service:
            image: myapp-service
            env_file: 
               - common.env
            ports:
               - 8080:8080
                 volumes:
                 - "./target/myapp-service.jar:/myapp-service.jar"
            depends_on: 
               - database

    database:
            image: mongo
            env_file:
               - common.env
            volumes:
               - "./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro"
            ports:
               - "27017-27019:27017-27019"

I have a custom login form, and running in Eclipse it works just fine. This is what I get when I run the whole thing in docker and navigate to the web page:

 myapp-service_1  | 2020-05-04 00:20:27.083 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /login reached end of additional filter chain; proceeding with original chain
myapp-service_1  | 2020-05-04 00:20:27.083 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet        : GET "/login", parameters={}
myapp-service_1  | 2020-05-04 00:20:27.084 DEBUG 1 --- [nio-8080-exec-8] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.sammckee.data.controller.LoginController#login()
myapp-service_1  | 2020-05-04 00:20:27.085 DEBUG 1 --- [nio-8080-exec-8] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
myapp-service_1  | 2020-05-04 00:20:27.085 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.view.JstlView            : View name 'login', model {}
myapp-service_1  | 2020-05-04 00:20:27.086 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.view.JstlView            : Forwarding to [/WEB-INF/views/login.jsp]
myapp-service_1  | 2020-05-04 00:20:27.092 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@49e79d09
myapp-service_1  | 2020-05-04 00:20:27.092 DEBUG 1 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet        : Completed 404 NOT_FOUND
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@6c18ca17. A new one will be created.
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/error'; against '/logout'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'POST /logout'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'PUT /logout'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'DELETE /logout'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /error' doesn't match 'POST /login'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.s.DefaultSavedRequest            : pathInfo: both null (property equals)
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.s.DefaultSavedRequest            : queryString: both null (property equals)
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.s.DefaultSavedRequest            : requestURI: arg1=/; arg2=/error (property not equals)
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.s.HttpSessionRequestCache        : saved request doesn't match
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
myapp-service_1  | 2020-05-04 00:20:27.093 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@48fd2a32: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: 172.30.0.1; SessionId: 7F4F9718EE23E9AA0244329F374437D3; Granted Authorities: ROLE_ANONYMOUS'
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.security.web.FilterChainProxy        : /error reached end of additional filter chain; proceeding with original chain
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}
myapp-service_1  | 2020-05-04 00:20:27.094 DEBUG 1 --- [nio-8080-exec-8] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
myapp-service_1  | 2020-05-04 00:20:27.097 DEBUG 1 --- [nio-8080-exec-8] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
myapp-service_1  | 2020-05-04 00:20:27.097 DEBUG 1 --- [nio-8080-exec-8] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 404
myapp-service_1  | 2020-05-04 00:20:27.097 DEBUG 1 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
myapp-service_1  | 2020-05-04 00:20:27.097 DEBUG 1 --- [nio-8080-exec-8] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
myapp-service_1  | 2020-05-04 00:20:27.097 DEBUG 1 --- [nio-8080-exec-8] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed

Any thoughts on what I might be missing? Again, it works fine in Eclipse. Sorry for the long log text--I wanted to make sure I was giving all the info necessary.

Edit/addendum:
When I navigate to the web app I see this:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Mon May 04 00:20:27 GMT 2020
There was an unexpected error (type=Not Found, status=404).
/WEB-INF/views/login.jsp

My DAOs derive from a class that connects to the database like this:

String client_url = "mongodb://" + dbuser + ":" + dbpassword + "@" + hostName + ":" + 27017 + "/"
						+ databaseName;

...where the host name, database, user and password are passed in by environment variables.

For the hostname I'm passing in "database" because that's the container name--that's how it should work in the container, right? When I run it in Eclipse I pass in "localhost" for the host name because the database container exposes the same port number to the local environment, and it works fine. I sort of expect to see database error messages if it's a problem with my mongo connection, but maybe not.

Edit/Addendum 2:
It definitely looks like there's something Springy I'm doing wrong. I made a little shell script to set the environment variables and run the jar file standalone in bash, outside the container, and it works as expected. Inside the docker container, I get errors. This is the part of the log that catches my eye:

Returning cached instance of singleton bean 'loginController'
 s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.myapp.bank.controller.LoginController#login()
 .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: []
 o.s.w.s.v.InternalResourceViewResolver   : View with key 
	
此处为隐藏的内容
注册登录后,方可查看
served from cache o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.JstlView: name 'login'; URL [/WEB-INF/views/login.jsp]] o.s.web.servlet.view.JstlView : View name 'login', model {} o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'requestDataValueProcessor' o.s.web.servlet.view.JstlView : Forwarding to [/WEB-INF/views/login.jsp] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@70ad1909 w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND, headers={masked} o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally

Edit/Addendum 3:
Still stumped. What I have confirmed is that I can copy the jar file to other places, and it runs fine there, serves up JSPs as expected and does everything I want it to do. So it seems to me the jar file itself must be okay. I'm mystified by what might be different when it's inside docker.

huangapple
  • 本文由 发表于 2020年5月4日 08:38:10
  • 转载请务必保留本文链接:https://java.coder-hub.com/61583478.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定