Docker Compose 用于 Java 后端和 Python 前端应用程序。

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

Docker compose for java backend and python frontend application

问题

以下是翻译好的内容:

我有一个简单的Spring Boot Java后端应用程序,可以从列表中获取元素(端点/get/{id})并将元素添加到列表中(端点/add/{product}):

  1. @RestController
  2. public class DemoController {
  3. List<String> products = Arrays.asList("test");
  4. @PostMapping(path="/add/{product}")
  5. public int addProduct(@PathVariable final String product){
  6. products.add(product);
  7. return products.size()-1;
  8. }
  9. @GetMapping(path="/get/{id}")
  10. public String getValue(@PathVariable final int id){
  11. return products.get(id);
  12. }
  13. }

我为此创建了Dockerfile,如下所示:

  1. FROM openjdk:11
  2. # 将打包的jar文件复制到我们的Docker镜像中
  3. COPY target/demo-0.0.1-SNAPSHOT.jar /demo.jar
  4. EXPOSE 8080/tcp
  5. # 设置启动命令以执行jar文件
  6. CMD ["java", "-jar", "/demo.jar"]

现在我可以构建镜像(docker build -t java_backend .)并运行应用程序(docker run --rm -p 8080:8080 java_backend)。

因此,在localhost:8080/get/0下,我得到了"test",在localhost:8080/add/something下,我可以添加元素。一切正常。

作为前端,我有一个简单的Python应用程序,如下所示:

  1. from flask import Flask, request
  2. import requests as r
  3. import os
  4. app = Flask(__name__)
  5. @app.route("/")
  6. def renderProduct():
  7. return """
  8. <html>
  9. <head>
  10. <title>""" + os.environ["title"] + """</title>
  11. </head>
  12. <form id="1" method="POST">
  13. <input name="getID"/>
  14. <br>
  15. <input name="addID">
  16. <input type="submit">
  17. </form>
  18. </html>
  19. """
  20. @app.route("/", methods=["POST"])
  21. def queryAndRender():
  22. builded = "<html>"
  23. if request.form["getID"] is not None:
  24. resp = r.get("http://localhost:8080/get/" + request.form["getID"])
  25. builded = builded + "PRODUCT:" + resp.text + "<br>"
  26. if request.form["addID"] is not None:
  27. resp = r.get("http://localhost:8080/add/" + request.form["addID"])
  28. builded = builded + "ADDED ID:" + resp.text + "<br>"
  29. builded = builded + """<html>
  30. <head>
  31. <title>""" + os.environ["title"] + """</title>
  32. </head>
  33. <form id="1" method="POST">
  34. <input name="getID"/>
  35. <br>
  36. <input name="addID">
  37. <input type="submit">
  38. </form>
  39. </html>
  40. """
  41. return builded;
  42. if __name__ == "__main__":
  43. app.run()

Dockerfile如下:

  1. ARG version=3.8.5-alpine3.11
  2. FROM python:${version}
  3. ENV title="Hello world"
  4. ENV test testspacja
  5. ENV FLASK_APP=/main.py
  6. RUN pip install Flask==1.1.2
  7. RUN pip install requests==2.22.0
  8. COPY main.py /
  9. RUN sed -i 's/localhost:8080/backend/g' /main.py
  10. EXPOSE 80/tcp
  11. ENTRYPOINT ["flask", "run"]
  12. CMD ["-h", "0.0.0.0", "-p", "80"]

最后,我创建了docker-compose.yml文件来运行它们两个:

  1. version: '3.3'
  2. services:
  3. backend:
  4. image: java_backend
  5. ports:
  6. - "8080:8080"
  7. frontend:
  8. image: frontend
  9. ports:
  10. - "8081:80"

现在我尝试启动docker-compose up --build backend frontend

前端和后端是独立工作的,因此如果我尝试在localhost:8080/get/0中放置localhost:8080/get/0,我会得到"test",如果我转到localhost:8081,我会看到我的前端。但是,如果我在文本框中输入一些值并单击提交,我会收到500 Internal Server Error。因此,服务之间没有连接。您能告诉我为什么吗?

英文:

I have simple spring boot java backend application which get element from the list (endpoint /get/{id}) and add element to the list (endpoint /add/{product}):

  1. @RestController
  2. public class DemoController {
  3. List&lt;String&gt; products = Arrays.asList(&quot;test&quot;);
  4. @PostMapping(path=&quot;/add/{product}&quot;)
  5. public int addProduct(@PathVariable final String product){
  6. products.add(product);
  7. return products.size()-1;
  8. }
  9. @GetMapping(path=&quot;/get/{id}&quot;)
  10. public String getValue(@PathVariable final int id){
  11. return products.get(id);
  12. }
  13. }

I created Dockerfile for this like:

  1. FROM openjdk:11
  2. # copy the packaged jar file into our docker image
  3. COPY target/demo-0.0.1-SNAPSHOT.jar /demo.jar
  4. EXPOSE 8080/tcp
  5. # set the startup command to execute the jar
  6. CMD [&quot;java&quot;, &quot;-jar&quot;, &quot;/demo.jar&quot;]

Now I can build image (docker build -t java_backend .) and run application (docker run --rm -p 8080:8080 java_backend).

Thus, under localhost:8080/get/0 I got &quot;test&quot;, under localhost:8080/add/something I can add element. Everything is fine.

As frontend I have simple python application like:

  1. from flask import Flask, request
  2. import requests as r
  3. import os
  4. app = Flask(__name__)
  5. @app.route(&quot;/&quot;)
  6. def renderProduct():
  7. return &quot;&quot;&quot;
  8. &lt;html&gt;
  9. &lt;head&gt;
  10. &lt;title&gt;&quot;&quot;&quot; + os.environ[&quot;title&quot;] + &quot;&quot;&quot;&lt;/title&gt;
  11. &lt;/head&gt;
  12. &lt;form id=&quot;1&quot; method=&quot;POST&quot;&gt;
  13. &lt;input name=&quot;getID&quot;/&gt;
  14. &lt;br&gt;
  15. &lt;input name=&quot;addID&quot;&gt;
  16. &lt;input type=&quot;submit&quot;&gt;
  17. &lt;/form&gt;
  18. &lt;/html&gt;
  19. &quot;&quot;&quot;
  20. @app.route(&quot;/&quot;, methods=[&quot;POST&quot;])
  21. def queryAndRender():
  22. builded = &quot;&lt;html&gt;&quot;
  23. if request.form[&quot;getID&quot;] is not None:
  24. resp = r.get(&quot;http://localhost:8080/get/&quot; + request.form[&quot;getID&quot;])
  25. builded = builded + &quot;PRODUCT:&quot; + resp.text + &quot;&lt;br&gt;&quot;
  26. if request.form[&quot;addID&quot;] is not None:
  27. resp = r.get(&quot;http://localhost:8080/add/&quot; + request.form[&quot;addID&quot;])
  28. builded = builded + &quot;ADDED ID:&quot; + resp.text + &quot;&lt;br&gt;&quot;
  29. builded = builded + &quot;&quot;&quot;&lt;html&gt;
  30. &lt;head&gt;
  31. &lt;title&gt;&quot;&quot;&quot; + os.environ[&quot;title&quot;] + &quot;&quot;&quot;&lt;/title&gt;
  32. &lt;/head&gt;
  33. &lt;form id=&quot;1&quot; method=&quot;POST&quot;&gt;
  34. &lt;input name=&quot;getID&quot;/&gt;
  35. &lt;br&gt;
  36. &lt;input name=&quot;addID&quot;&gt;
  37. &lt;input type=&quot;submit&quot;&gt;
  38. &lt;/form&gt;
  39. &lt;/html&gt;
  40. &quot;&quot;&quot;
  41. return builded;
  42. if __name__ == &quot;__main__&quot;:
  43. app.run()

And Dockerfile:

  1. ARG version=3.8.5-alpine3.11
  2. FROM python:${version}
  3. ENV title=&quot;Hello world&quot;
  4. ENV test testspacja
  5. ENV FLASK_APP=/main.py
  6. RUN pip install Flask==1.1.2
  7. RUN pip install requests==2.22.0
  8. COPY main.py /
  9. RUN sed -i &#39;s/localhost:8080/backend/g&#39; /main.py
  10. EXPOSE 80/tcp
  11. ENTRYPOINT [&quot;flask&quot;, &quot;run&quot;]
  12. CMD [&quot;-h&quot;, &quot;0.0.0.0&quot;, &quot;-p&quot;, &quot;80&quot;]

At the end I created docker-compose.yml file to run both of them:

  1. version: &#39;3.3&#39;
  2. services:
  3. backend:
  4. image: java_backend
  5. ports:
  6. - &quot;8080:8080&quot;
  7. frontend:
  8. image: frontend
  9. ports:
  10. - &quot;8081:80&quot;

Now I try to start docker-compose up --build backend frontend.

Frontend and backend are working independent, hence if I try put localhost:8080/get/0 I am getting &quot;test&quot;, If I go to localhost:8081 I see my frontend. But if I put some values in textboxes and click submit then I got 500 Internal Server Error. So services are not connected. Could you please tell me why?

答案1

得分: 0

我认为你在意外地擦除了后端端口。尝试将以下内容替换为:

  1. RUN sed -i &#39;s/localhost:8080/backend:8080/g&#39; /main.py
英文:

I think you are accidentally erasing the backend port. Try replacing

  1. RUN sed -i &#39;s/localhost:8080/backend/g&#39; /main.py

with

  1. RUN sed -i &#39;s/localhost:8080/backend:8080/g&#39; /main.py

答案2

得分: 0

我有一个额外的问题。假设我想从容器中启动前端,但只从我的本地IDE(IntelliJ)启动后端。

当然,RUN sed -i 's/localhost:8080/backend/g' /main.py 这一行被注释了,所以前端调用的是 http://localhost:8080 下的端点。

在这种情况下,前端位于 http://localhost:8081,后端位于 http://localhost:8080(两个端点 - /get/{id}/add/{product})。但为什么在容器中运行的前端无法“看到”我的后端呢?

英文:

I have one additional question for this. Let's suppose that I would like start frontend from container but backend only from the my local IDE (IntelliJ).

Of course line RUN sed -i &#39;s/localhost:8080/backend/g&#39; /main.py is commented so frontent is calling endpoints under http://localhost:8080.

In this case frontend is under http://localhost:8081 and backend under http://localhost:8080 (two endpoints - /get/{id} and /add/{product}). But why frontend which is running in container doesn't "see" my backend?

huangapple
  • 本文由 发表于 2020年9月20日 23:59:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63980939.html
匿名

发表评论

匿名网友

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

确定