Access localhost from within a docker image.

huangapple go评论90阅读模式
英文:

Access localhost from within a docker image

问题

以下是翻译好的内容:

  1. 我有以下的 .gitlab-ci.yml 文件:
  2. 图像: python:3.8
  3. variables:
  4. PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  5. cache:
  6. paths:
  7. - .cache/pip
  8. - venv/
  9. before_script:
  10. - python -V # 用于调试打印 Python 版本
  11. - pip install --upgrade pip
  12. - pip install virtualenv
  13. - virtualenv venv
  14. - source venv/bin/activate
  15. - pip install -r requirements.txt
  16. - cp properties_ci properties
  17. - apt-get update
  18. - apt-get install net-tools
  19. stages:
  20. - build
  21. - test
  22. - security
  23. - leanix
  24. include:
  25. - ...
  26. test:unit:
  27. stage: ...
  28. test:integration:
  29. stage: test
  30. script:
  31. - echo "0"
  32. - python app.py &
  33. - curl 127.0.0.1:8126
  34. - py.test tests/integration/test_integration.py
  35. services:
  36. - name: cassandra:3.11

当我使用命令 python app.py 启动我的 Python 应用程序时,我可以看到以下输出:

  1. $ python app.py
  2. 警告:cassandra.cluster:Cluster.__init__ 调用时指定了 contact_points,但没有指定 load_balancing_policy。在下一个主要版本中,这将引发错误;请指定一个负载均衡策略。(contact_points = ['cassandra'], lbp = None)
  3. 警告:cassandra.connection:未发送身份验证挑战,这很可疑,因为驱动程序预期进行身份验证(配置的 authenticator = PlainTextAuthenticator)
  4. 警告:cassandra.connection:未发送身份验证挑战,这很可疑,因为驱动程序预期进行身份验证(配置的 authenticator = PlainTextAuthenticator)
  5. 创建 keyspace(如果不存在)...
  6. 创建 tables(如果不存在)...
  7. * 提供 Flask 应用 'src' (延迟加载)
  8. * 环境: production
  9. 警告: 这是一个开发服务器。请勿在生产部署中使用它。
  10. 请改用生产 WSGI 服务器。
  11. * 调试模式: 关闭
  12. INFO:werkzeug:警告: 这是一个开发服务器。请勿在生产部署中使用它。
  13. * 运行在 http://127.0.0.1:8126

因此,连接到 Cassandra 并创建/插入数据工作正常,但集成测试无法访问本地主机上的 Python 应用程序。

在我的集成测试中,我调用 http://127.0.0.1:8126,但显示以下信息:

  1. 创建 keyspace(如果不存在)...
  2. =========================== 简短的测试摘要信息 ============================
  3. 错误 tests/integration/test_integration.py - requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8126): Max retries exceeded with url: /getCSRFToken (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f316d3df700>: Failed to establish a new connection: [Errno 111] Connection refused'))
  4. !!!!!!!!!!!!!!!!!!!! 中断: 收集期间的 1 个错误 !!!!!!!!!!!!!!!!!!!!
  5. =============================== 3.05 秒内的 1 个错误 ===============================

如何在 Docker 容器内调用本地主机以便访问我的应用程序?我尝试了 127.0.0.1 也不起作用。

编辑 1:

脚本 test_integration.py 包含以下代码的小示例部分:

  1. ...
  2. url = "http://localhost:8126/series/"
  3. import zipfile
  4. with zipfile.ZipFile("tests/integration/20230323.zip", mode="r") as archive:
  5. # 遍历 zip 文件中的文件
  6. for zipfilename in archive.filelist:
  7. txtdata = archive.read(zipfilename)
  8. if (zipfilename.filename == 'OP_lastchange_CRUDE_2023-03-23.json'):
  9. payload2 = json.dumps(json.loads(txtdata))
  10. response = requests.request("POST", url, headers=headers, data=payload2)
  11. assert response.status_code == 204, "圣诞老人今年不来了!"
  12. ...

编辑 2:

解决方案由 @KamilCuk 提供 - 在 before_script 部分将 Python 应用程序设置为在后台运行,如 python app.py &,并休眠几秒钟,使我的 Python 应用程序可用于调用,例如 http://localhost:8126

英文:

I have the following .gitlab-ci.yml file :

  1. image: python:3.8
  2. variables:
  3. PIP_CACHE_DIR: &quot;$CI_PROJECT_DIR/.cache/pip&quot;
  4. cache:
  5. paths:
  6. - .cache/pip
  7. - venv/
  8. before_script:
  9. - python -V # Print out python version for debugging
  10. - pip install --upgrade pip
  11. - pip install virtualenv
  12. - virtualenv venv
  13. - source venv/bin/activate
  14. - pip install -r requirements.txt
  15. - cp properties_ci properties
  16. - apt-get update
  17. - apt-get install net-tools
  18. stages:
  19. - build
  20. - test
  21. - security
  22. - leanix
  23. include:
  24. - ...
  25. test:unit:
  26. stage: ...
  27. test:integration:
  28. stage: test
  29. script:
  30. - echo &quot;0&quot;
  31. - python app.py &amp;
  32. - curl 127.0.0.1:8126
  33. - py.test tests/integration/test_integration.py
  34. services:
  35. - name: cassandra:3.11

When I launch my python application by using the command python app.py I can see the following output :

  1. $ python app.py
  2. WARNING:cassandra.cluster:Cluster.__init__ called with contact_points specified, but no load_balancing_policy. In the next major version, this will raise an error; please specify a load-balancing policy. (contact_points = [&#39;cassandra&#39;], lbp = None)
  3. WARNING:cassandra.connection:An authentication challenge was not sent, this is suspicious because the driver expects authentication (configured authenticator = PlainTextAuthenticator)
  4. WARNING:cassandra.connection:An authentication challenge was not sent, this is suspicious because the driver expects authentication (configured authenticator = PlainTextAuthenticator)
  5. Creating keyspace if not exist...
  6. Creating tables if not exist...
  7. * Serving Flask app &#39;src&#39; (lazy loading)
  8. * Environment: production
  9. WARNING: This is a development server. Do not use it in a production deployment.
  10. Use a production WSGI server instead.
  11. * Debug mode: off
  12. INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
  13. * Running on http://127.0.0.1:8126

So connecting to Cassandra and creating/inserting data works well, but the integration tests cannot access the python application on localhost.

In my integration tests I call http://127.0.0.1:8126 but it says the following :

  1. Creating keyspace if not exist...
  2. =========================== short test summary info ============================
  3. ERROR tests/integration/test_integration.py - requests.exceptions.ConnectionError: HTTPConnectionPool(host=&#39;localhost&#39;, port=8126): Max retries exceeded with url: /getCSRFToken (Caused by NewConnectionError(&#39;&lt;urllib3.connection.HTTPConnection object at 0x7f316d3df700&gt;: Failed to establish a new connection: [Errno 111] Connection refused&#39;))
  4. !!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
  5. =============================== 1 error in 3.05s ===============================

Any ideas how to call localhost inside the docker container so that I can access my application ? I tried also 127.0.0.1 and it does not work.

EDIT 1

The script test_integration.py contains as a small example the following portion of code :

  1. ...
  2. url = &quot;http://localhost:8126/series/&quot;
  3. import zipfile
  4. with zipfile.ZipFile(&quot;tests/integration/20230323.zip&quot;, mode=&quot;r&quot;) as archive:
  5. #Iterate through files in zip file
  6. for zipfilename in archive.filelist:
  7. txtdata = archive.read(zipfilename)
  8. if (zipfilename.filename == &#39;OP_lastchange_CRUDE_2023-03-23.json&#39;):
  9. payload2 = json.dumps(json.loads(txtdata))
  10. response = requests.request(&quot;POST&quot;, url, headers=headers, data=payload2)
  11. assert response.status_code == 204, &quot;Santa Claus is not coming this year !&quot;
  12. ...

EDIT 2

The solution is given by @KamilCuk - setting the python app to run in the background in the section before_script like python app.py &amp; and sleeping for several seconds makes my python application available to be called like http://localhost:8126.

答案1

得分: 1

请查看夹具替代方案。将以下内容放入您的 conftest.py 文件中:

  1. @pytest.fixture(scope="session")
  2. def app(request):
  3. pp = subprocess.Popen("python app.py", shell=True)
  4. time.sleep(5) # TODO: 替换为等待端口打开
  5. request.addfinalizer(lambda: (pp.terminate(), pp.wait()))
  6. return pp

然后在测试中使用:

  1. def test_something(app):
  2. pass
英文:

Instead consider fixtures. Put the following in your conftest.py:

  1. @pytest.fixture(scope=&quot;session&quot;)
  2. def app(request):
  3. pp = subprocess.popen(&quot;python app.py&quot;)
  4. time.sleep(5) # TODO: replace with waiting for open port
  5. request.addfinalizer(lambda: (pp.terminate(), pp.wait()))
  6. return pp

Then in tests use:

  1. def test_something(app):
  2. pass

答案2

得分: 0

以下是代码部分的中文翻译:

  1. image: python:3.8
  2. variables:
  3. PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  4. cache:
  5. paths:
  6. - .cache/pip
  7. - venv/
  8. before_script:
  9. - ...
  10. - python app.py &
  11. - sleep 20 # 等待应用程序启动
  12. stages:
  13. - 构建
  14. - 运行
  15. - 测试
  16. - 安全
  17. - leanix
  18. include:
  19. - 项目: ...
  20. services:
  21. - 名称: cassandra:3.11
  22. 别名: cassandra
  23. test:unit:
  24. 阶段: ...
  25. test:integration:
  26. 阶段: 测试
  27. 脚本:
  28. - echo "0"
  29. - py.test tests/integration/test_series.py

请注意,代码中的注释部分没有翻译。

英文:

One of the working solutions, in my case, proposed by KamilCuk, is the following :

  1. image: python:3.8
  2. variables:
  3. PIP_CACHE_DIR: &quot;$CI_PROJECT_DIR/.cache/pip&quot;
  4. cache:
  5. paths:
  6. - .cache/pip
  7. - venv/
  8. before_script:
  9. - ...
  10. - python app.py &amp;
  11. - sleep 20 # wait for application to start-up
  12. stages:
  13. - build
  14. - run
  15. - test
  16. - security
  17. - leanix
  18. include:
  19. - project: ...
  20. services:
  21. - name: cassandra:3.11
  22. alias: cassandra
  23. test:unit:
  24. stage: ...
  25. test:integration:
  26. stage: test
  27. script:
  28. - echo &quot;0&quot;
  29. - py.test tests/integration/test_series.py

The solution is given by @KamilCuk - setting the python app to run in the background in the section before_script like python app.py &amp; and sleeping for several seconds sleep 20 makes my python application available to be called like http://localhost:8126.

I need to investigate the other solution proposed by KamilCuk using fixtures.

huangapple
  • 本文由 发表于 2023年4月11日 17:00:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75984105.html
匿名

发表评论

匿名网友

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

确定