【问题标题】:Dockerized Redmine, not responding API Rest requestsDockerized Redmine,不响应 API Rest 请求
【发布时间】:2021-06-28 16:07:57
【问题描述】:

问题:(总结) 我有一个 Redmine 在一个位于 VM 中的 docker 容器上运行(Centos 8,但我也在 Ubuntu 18 服务器上尝试过,我得到了相同的结果)。当我通过 API Rest 发出请求时,我收到“超时”错误或类似错误。

更多信息:

  • 我编写了一个程序,通过它的 API Rest 服务向 Redmine 发出大量请求。在本地安装在 VM 中的 Redmine 上测试了相同的程序,并且一切正常。这使我认为我的程序不是问题。

  • 例如,当我直接在浏览器上编写 http://ip_of_my_dockerized_redmine:port/users.json (根据the Redmine api rest documentation 返回用户列表)时,它工作得很好,并在浏览器。

  • 当然,我已经通过 web ui 激活了 REST web 服务。

我的程序是用 python 编写的,所以这就是我使用 python request 库向服务器发出请求的原因。但是,我也使用了 Postman,结果是一样的。以下是我收到的一些错误。

我的 docker 撰写文件:

version: '3.8'

services:

  postgres:
    image: 'postgres:13'
    container_name: 'contenedor_postgres'
    restart: always
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      - 'POSTGRES_PASSWORD=<some password>'
      - 'POSTGRES_DB=redmine'

  redmine:
    image: 'redmine:4.2.1'
    container_name: 'contenedor_redmine'
    restart: always
    volumes:
      - redmine-data:/usr/src/redmine/files
      - redmine-plugins:/usr/src/redmine/plugins
    ports:
      - 3000:3000
    environment:
      - 'REDMINE_DB_POSTGRES=postgres'
      - 'REDMINE_DB_DATABASE=redmine'
      - 'REDMINE_DB_PASSWORD=<a password>'

volumes:
  postgres-data:
  redmine-data:
  redmine-plugins:

这是一个从 jupyter Notebook 发出的 Python 请求,(已经在本地运行的 Redmine 上测试过)

# The credentials and other auth. data are stored here
from app import connection
# The request library
import requests
url = "http://ip:3000"
# The request in question.
response = requests.get( url + "/user.json", verify=False, auth=( connection.REDMINE_USER, connection.REDMINE_PASSWORD), timeout=20)
response

您可以看到我已经引入了timeout=20 参数,正如其他类似帖子中提到的那样它可以工作,但它没有。

回复是:

---------------------------------------------------------------------------
timeout                                   Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py in _new_conn(self)
    168         try:
--> 169             conn = connection.create_connection(
    170                 (self._dns_host, self.port), self.timeout, **extra_kw

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\connection.py in create_connection(address, timeout, source_address, socket_options)
     95     if err is not None:
---> 96         raise err
     97 

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\connection.py in create_connection(address, timeout, source_address, socket_options)
     85                 sock.bind(source_address)
---> 86             sock.connect(sa)
     87             return sock

timeout: timed out

During handling of the above exception, another exception occurred:

ConnectTimeoutError                       Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    698             # Make the request on the httplib connection object.
--> 699             httplib_response = self._make_request(
    700                 conn,

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    393             else:
--> 394                 conn.request(method, url, **httplib_request_kw)
    395 

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py in request(self, method, url, body, headers)
    233             headers["User-Agent"] = _get_default_user_agent()
--> 234         super(HTTPConnection, self).request(method, url, body=body, headers=headers)
    235 

~\AppData\Local\Programs\Python\Python39\lib\http\client.py in request(self, method, url, body, headers, encode_chunked)
   1254         """Send a complete request to the server."""
-> 1255         self._send_request(method, url, body, headers, encode_chunked)
   1256 

~\AppData\Local\Programs\Python\Python39\lib\http\client.py in _send_request(self, method, url, body, headers, encode_chunked)
   1300             body = _encode(body, 'body')
-> 1301         self.endheaders(body, encode_chunked=encode_chunked)
   1302 

~\AppData\Local\Programs\Python\Python39\lib\http\client.py in endheaders(self, message_body, encode_chunked)
   1249             raise CannotSendHeader()
-> 1250         self._send_output(message_body, encode_chunked=encode_chunked)
   1251 

~\AppData\Local\Programs\Python\Python39\lib\http\client.py in _send_output(self, message_body, encode_chunked)
   1009         del self._buffer[:]
-> 1010         self.send(msg)
   1011 

~\AppData\Local\Programs\Python\Python39\lib\http\client.py in send(self, data)
    949             if self.auto_open:
--> 950                 self.connect()
    951             else:

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py in connect(self)
    199     def connect(self):
--> 200         conn = self._new_conn()
    201         self._prepare_conn(conn)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py in _new_conn(self)
    173         except SocketTimeout:
--> 174             raise ConnectTimeoutError(
    175                 self,

ConnectTimeoutError: (<urllib3.connection.HTTPConnection object at 0x000000B37871A940>, 'Connection to <my_vm_ip> timed out. (connect timeout=20)')

During handling of the above exception, another exception occurred:

MaxRetryError                             Traceback (most recent call last)
~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    438             if not chunked:
--> 439                 resp = conn.urlopen(
    440                     method=request.method,

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    754 
--> 755             retries = retries.increment(
    756                 method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]

~\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\retry.py in increment(self, method, url, response, error, _pool, _stacktrace)
    572         if new_retry.is_exhausted():
--> 573             raise MaxRetryError(_pool, url, error or ResponseError(cause))
    574 

MaxRetryError: HTTPConnectionPool(host='<my_vm_ip>', port=3000): Max retries exceeded with url: /user.json (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000000B37871A940>, 'Connection to <my_vm_ip> timed out. (connect timeout=20)'))

During handling of the above exception, another exception occurred:

ConnectTimeout                            Traceback (most recent call last)
<ipython-input-3-dc378d70e4d9> in <module>
----> 1 response = requests.get( url + "/user.json", verify=False, auth=( connection.REDMINE_USER, connection.REDMINE_PASSWORD), timeout=20)
      2 
      3 response

~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py in get(url, params, **kwargs)
     74 
     75     kwargs.setdefault('allow_redirects', True)
---> 76     return request('get', url, params=params, **kwargs)
     77 
     78 

~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py in request(method, url, **kwargs)
     59     # cases, and look like a memory leak in others.
     60     with sessions.Session() as session:
---> 61         return session.request(method=method, url=url, **kwargs)
     62 
     63 

~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    540         }
    541         send_kwargs.update(settings)
--> 542         resp = self.send(prep, **send_kwargs)
    543 
    544         return resp

~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py in send(self, request, **kwargs)
    653 
    654         # Send the request
--> 655         r = adapter.send(request, **kwargs)
    656 
    657         # Total elapsed time of the request (approximately)

~\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    502                 # TODO: Remove this in 3.0.0: see #2811
    503                 if not isinstance(e.reason, NewConnectionError):
--> 504                     raise ConnectTimeout(e, request=request)
    505 
    506             if isinstance(e.reason, ResponseError):

ConnectTimeout: HTTPConnectionPool(host='<my_vm_ip>', port=3000): Max retries exceeded with url: /user.json (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000000B37871A940>, 'Connection to <my_vm_ip> timed out. (connect timeout=20)'))

尝试使用 Postman 发出相同的请求会得到相同的结果:

GET http://<my_vm_ip>:3000/users.json
Error: connect ETIMEDOUT <my_vm_ip>:3000
Request Headers
Authorization: Basic YW***************mQ=
User-Agent: PostmanRuntime/7.28.1
Accept: */*
Postman-Token: b52f****************3de0fbe
Host: <my_vm_ip>:3000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

我有感觉,这可能是与 Docker 相关的问题,但我不知道。我不是 Docker tbh 方面的专家。

编辑#1: 仅出于更新的目的,我尝试使端口可以访问防火墙(在这种情况下,firewalld 因为是 Redhat),所以:

firewall-cmd --permanent --add-port=3000/tcp

firewall-cmd --permanent --add-port=5432/tcp

返回succeed,但结果是一样的。不工作。

编辑#2: 我也尝试使用库python-redmine,但结果是相似的。

TimeoutError: [WinError 10060]

【问题讨论】:

  • 你检查过 redmine 日志 (docker logs contenedor_redmine) 吗?你能在日志中看到以超时结束的请求吗?
  • 我做到了,有趣的是我没有收到任何我的请愿书。我做的唯一方法是当我在 Web 浏览器上明确提出请求时,最后一个日志是 ip_vm:3000/my/page -> / ip_requesting - - [10/Jun/2021:05:35:34 UTC] "GET /users. json HTTP/1.1" 200 329 - -> /users.json 这也应该是另一种方式。

标签: docker rest docker-compose postman redmine


【解决方案1】:

请原谅我的问题,但没有提及:您可以通过 http 访问您的 Redmine 实例并从那里启用 Rest API 吗?

消除了我会查看 VM 防火墙设置以查看是否可以访问 3000。

为了快速测试,您可以将 docker 设置为通过端口 80 公开 redmine 的 3000 端口:

redmine:
    image: 'redmine:4.2.1'
    container_name: 'contenedor_redmine'
    ...
    ports:
      - 80:3000
    ...

【讨论】:

  • 是的,正如我所提到的,我确实按照文档中的想法启用了 REST Web 服务。 (管理->设置-> API->启用Rest Web服务)我确实将端口3000更改为80,但我什至无法进入Redmine。 ("http // ip:80") 导致“ERR_CONNECTION_TIMED_OUT”
  • 我的错。 Docker compose 端口配置映射是 HOST_PORT:CONTAINER_PORT。编辑响应以使端口配置:80:3000
  • 此后的行为也没有变化。结果相同。不过我觉得有点奇怪。另外,我相信不会打击 docker 容器,因为它不会在其日志上生成注册表。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 2014-09-01
  • 2018-03-26
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
相关资源
最近更新 更多