Docker에 최소 플라스크 앱 배포-서버 연결 문제
나는 유일한 의존성 인 앱이 플라스크이며, 이는 docker 외부에서 잘 실행되고 기본 포트에 바인딩됩니다 5000
. 다음은 전체 소스입니다.
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route('/')
def main():
return 'hi'
if __name__ == '__main__':
app.run()
문제는 이것을 docker에 배포하면 서버가 실행 중이지만 컨테이너 외부에서 연결할 수 없다는 것입니다.
아래는 내 Dockerfile입니다. 이미지는 플라스크가 설치된 우분투입니다. tar에는 index.py
위에 나열된 내용 만 포함 됩니다.
# Dockerfile
FROM dreen/flask
MAINTAINER dreen
WORKDIR /srv
# Get source
RUN mkdir -p /srv
COPY perfektimprezy.tar.gz /srv/perfektimprezy.tar.gz
RUN tar x -f perfektimprezy.tar.gz
RUN rm perfektimprezy.tar.gz
# Run server
EXPOSE 5000
CMD ["python", "index.py"]
배포하기 위해 수행하는 단계는 다음과 같습니다.
$> sudo docker build -t perfektimprezy .
위의 내용이 잘 실행되는 한 이미지에는 /srv
. 이제 컨테이너에서 서버를 시작하겠습니다.
$> sudo docker run -i -p 5000:5000 -d perfektimprezy
1c50b67d45b1a4feade72276394811c8399b1b95692e0914ee72b103ff54c769
실제로 실행 중입니까?
$> sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c50b67d45b1 perfektimprezy:latest "python index.py" 5 seconds ago Up 5 seconds 0.0.0.0:5000->5000/tcp loving_wozniak
$> sudo docker logs 1c50b67d45b1
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
네, 플라스크 서버가 실행중인 것 같습니다. 여기가 이상해집니다. 서버에 요청할 수 있습니다.
$> curl 127.0.0.1:5000 -v
* Rebuilt URL to: 127.0.0.1:5000/
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:5000
> Accept: */*
>
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server
빈 답장 ...하지만 프로세스가 실행 중입니까?
$> sudo docker top 1c50b67d45b1
UID PID PPID C STIME TTY TIME CMD
root 2084 812 0 10:26 ? 00:00:00 python index.py
root 2117 2084 0 10:26 ? 00:00:00 /usr/bin/python index.py
Now let's ssh into the server and check...
$> sudo docker exec -it 1c50b67d45b1 bash
root@1c50b67d45b1:/srv# netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:47677 127.0.0.1:5000 TIME_WAIT
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
root@1c50b67d45b1:/srv# curl -I 127.0.0.1:5000
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5447
Server: Werkzeug/0.10.4 Python/2.7.6
Date: Tue, 19 May 2015 12:18:14 GMT
It's fine... but not from the outside :( What am I doing wrong?
The problem is you are only binding to the localhost interface, you should be binding to 0.0.0.0
if you want the container to be accessible from outside. If you change:
if __name__ == '__main__':
app.run()
to
if __name__ == '__main__':
app.run(host='0.0.0.0')
It should work.
When using the flask
command instead of app.run
, you can pass the --host
option to change the host. The line in Docker would be:
CMD ["flask", "run", "--host", "0.0.0.0"]
or
CMD flask run --host 0.0.0.0
Your Docker container has more than one network interface. For example, my container has the following:
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
if you run docker network inspect bridge
, you can see that your container is connected to that bridge with the second interface in the above output. This default bridge is also connected to the Docker process on your host.
Therefore you would have to run the command:
CMD flask run --host 172.17.0.2
To access your Flask app running in a Docker container from your host machine. Replace 172.17.0.2
with whatever the particular IP address is of your container.
'developer tip' 카테고리의 다른 글
추가 클래스 경로 옵션을 사용하여 "java -jar MyFile.jar"호출 (0) | 2020.10.12 |
---|---|
pandas 데이터 프레임을 여러 열로 필터링하는 방법 (0) | 2020.10.12 |
JsonReader.setLenient (true)를 사용하여 1 행 1 열 경로 $에서 잘못된 형식의 JSON을 허용하십시오. (0) | 2020.10.12 |
ts ES5 / ES3의 비동기 함수 또는 메서드에는 'Promise'생성자가 필요합니다. (0) | 2020.10.12 |
print 문을 사용할 때 특수 문자 표시 (0) | 2020.10.12 |