英文:
Docker compose for java backend and python frontend application
问题
以下是翻译好的内容:
我有一个简单的Spring Boot Java后端应用程序,可以从列表中获取元素(端点/get/{id}
)并将元素添加到列表中(端点/add/{product}
):
@RestController
public class DemoController {
List<String> products = Arrays.asList("test");
@PostMapping(path="/add/{product}")
public int addProduct(@PathVariable final String product){
products.add(product);
return products.size()-1;
}
@GetMapping(path="/get/{id}")
public String getValue(@PathVariable final int id){
return products.get(id);
}
}
我为此创建了Dockerfile,如下所示:
FROM openjdk:11
# 将打包的jar文件复制到我们的Docker镜像中
COPY target/demo-0.0.1-SNAPSHOT.jar /demo.jar
EXPOSE 8080/tcp
# 设置启动命令以执行jar文件
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应用程序,如下所示:
from flask import Flask, request
import requests as r
import os
app = Flask(__name__)
@app.route("/")
def renderProduct():
return """
<html>
<head>
<title>""" + os.environ["title"] + """</title>
</head>
<form id="1" method="POST">
<input name="getID"/>
<br>
<input name="addID">
<input type="submit">
</form>
</html>
"""
@app.route("/", methods=["POST"])
def queryAndRender():
builded = "<html>"
if request.form["getID"] is not None:
resp = r.get("http://localhost:8080/get/" + request.form["getID"])
builded = builded + "PRODUCT:" + resp.text + "<br>"
if request.form["addID"] is not None:
resp = r.get("http://localhost:8080/add/" + request.form["addID"])
builded = builded + "ADDED ID:" + resp.text + "<br>"
builded = builded + """<html>
<head>
<title>""" + os.environ["title"] + """</title>
</head>
<form id="1" method="POST">
<input name="getID"/>
<br>
<input name="addID">
<input type="submit">
</form>
</html>
"""
return builded;
if __name__ == "__main__":
app.run()
Dockerfile如下:
ARG version=3.8.5-alpine3.11
FROM python:${version}
ENV title="Hello world"
ENV test testspacja
ENV FLASK_APP=/main.py
RUN pip install Flask==1.1.2
RUN pip install requests==2.22.0
COPY main.py /
RUN sed -i 's/localhost:8080/backend/g' /main.py
EXPOSE 80/tcp
ENTRYPOINT ["flask", "run"]
CMD ["-h", "0.0.0.0", "-p", "80"]
最后,我创建了docker-compose.yml
文件来运行它们两个:
version: '3.3'
services:
backend:
image: java_backend
ports:
- "8080:8080"
frontend:
image: frontend
ports:
- "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}
):
@RestController
public class DemoController {
List<String> products = Arrays.asList("test");
@PostMapping(path="/add/{product}")
public int addProduct(@PathVariable final String product){
products.add(product);
return products.size()-1;
}
@GetMapping(path="/get/{id}")
public String getValue(@PathVariable final int id){
return products.get(id);
}
}
I created Dockerfile for this like:
FROM openjdk:11
# copy the packaged jar file into our docker image
COPY target/demo-0.0.1-SNAPSHOT.jar /demo.jar
EXPOSE 8080/tcp
# set the startup command to execute the jar
CMD ["java", "-jar", "/demo.jar"]
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 "test"
, under localhost:8080/add/something
I can add element. Everything is fine.
As frontend I have simple python application like:
from flask import Flask, request
import requests as r
import os
app = Flask(__name__)
@app.route("/")
def renderProduct():
return """
<html>
<head>
<title>""" + os.environ["title"] + """</title>
</head>
<form id="1" method="POST">
<input name="getID"/>
<br>
<input name="addID">
<input type="submit">
</form>
</html>
"""
@app.route("/", methods=["POST"])
def queryAndRender():
builded = "<html>"
if request.form["getID"] is not None:
resp = r.get("http://localhost:8080/get/" + request.form["getID"])
builded = builded + "PRODUCT:" + resp.text + "<br>"
if request.form["addID"] is not None:
resp = r.get("http://localhost:8080/add/" + request.form["addID"])
builded = builded + "ADDED ID:" + resp.text + "<br>"
builded = builded + """<html>
<head>
<title>""" + os.environ["title"] + """</title>
</head>
<form id="1" method="POST">
<input name="getID"/>
<br>
<input name="addID">
<input type="submit">
</form>
</html>
"""
return builded;
if __name__ == "__main__":
app.run()
And Dockerfile:
ARG version=3.8.5-alpine3.11
FROM python:${version}
ENV title="Hello world"
ENV test testspacja
ENV FLASK_APP=/main.py
RUN pip install Flask==1.1.2
RUN pip install requests==2.22.0
COPY main.py /
RUN sed -i 's/localhost:8080/backend/g' /main.py
EXPOSE 80/tcp
ENTRYPOINT ["flask", "run"]
CMD ["-h", "0.0.0.0", "-p", "80"]
At the end I created docker-compose.yml
file to run both of them:
version: '3.3'
services:
backend:
image: java_backend
ports:
- "8080:8080"
frontend:
image: frontend
ports:
- "8081:80"
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 "test"
, 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
我认为你在意外地擦除了后端端口。尝试将以下内容替换为:
RUN sed -i 's/localhost:8080/backend:8080/g' /main.py
英文:
I think you are accidentally erasing the backend port. Try replacing
RUN sed -i 's/localhost:8080/backend/g' /main.py
with
RUN sed -i 's/localhost:8080/backend:8080/g' /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 's/localhost:8080/backend/g' /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?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论