ডকারে একটি সর্বনিম্ন ফ্লাস্ক অ্যাপ স্থাপন করা হচ্ছে - সার্ভার সংযোগের সমস্যা


114

আমার কাছে এমন একটি অ্যাপ রয়েছে যার একমাত্র নির্ভরতা হ'ল ফ্লাস্ক, যা ডকারের বাইরে সূক্ষ্মভাবে চলে এবং ডিফল্ট বন্দরে বাঁধে 5000। এখানে সম্পূর্ণ উত্স:

from flask import Flask

app = Flask(__name__)
app.debug = True

@app.route('/')
def main():
    return 'hi'

if __name__ == '__main__':
    app.run()

সমস্যাটি হ'ল আমি যখন এটি ডকারে স্থাপন করি তখন সার্ভারটি চলমান থাকে তবে ধারকটির বাইরে থেকে না পারা যায়।

নীচে আমার ডকফাইফিল রয়েছে। ছবিটি ফ্লাস্ক ইনস্টল করে উবুন্টু। টারে কেবল 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

এখন সার্ভারের মধ্যে ssh এবং পরীক্ষা করা যাক ...

$> 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

এটা ঠিক আছে ... তবে বাইরে থেকে নয় :( আমি কী ভুল করছি?


প্রাসঙ্গিক জিনিস "<বর্গ 'httplib.BadStatusLine'> দ্বারা সৃষ্ট" হয় দেখুন stackoverflow.com/questions/16592568/...
user2915097

আমি কেবল একবার সংযোগ দেওয়ার চেষ্টা করছি এবং আমি মোটামুটি নিশ্চিত যে এটি কোনও পোস্টি-তে কোনও বাগ নয় (আমি এখন কার্ল করার উদাহরণটি পরিবর্তন করেছি), না সার্ভারে যেমন এটি ডকের বাইরে ঠিকঠাক কাজ করে। আমার
দৃ strong়

আপনি কোনও ফ্লাস্ক (লেজ, বিড়াল ...) ডিবাগ করার সময় কন্টেইনারটি docker exec -it 1c50b67d45b1 bashএবং তারপরে সাধারণ netstat -anবা কোনও আদেশ আপনি যা করতে চান তা পরীক্ষা করুন
ব্যবহারকারী 2915097

@ ব্যবহারকারী 2915097: iv সার্ভারের মধ্যে থেকে কিছু আউটপুট যুক্ত করেছে
ড্রিন

'সংযুক্ত হতে পারে না ...' @ ড্রেইন, আপনি সংযোগ করতে পারবেন , আপনি কেবল একটি খালি উত্তর পাবেন ( Connected to 127.0.0.1)
ফোর্সব্রু

উত্তর:


190

সমস্যাটি হ'ল আপনি কেবল লোকালহোস্ট ইন্টারফেসের জন্য বাধ্য, আপনি 0.0.0.0যদি ধারকটি বাইরে থেকে অ্যাক্সেসযোগ্য হতে চান তবে আপনাকে বাধ্য করা উচিত । যদি আপনি পরিবর্তন করেন:

if __name__ == '__main__':
    app.run()

প্রতি

if __name__ == '__main__':
    app.run(host='0.0.0.0')

এটি কাজ করা উচিত.


এই সমাধান কাজ করে। এই সমাধানটির বর্ণনা অনুসারে এখানে একটি পূর্ণ ডকস্পিল এবং পাইথন স্ক্রিপ্ট ব্যবহার করে ফলাফল দেখতে পাবেন ।

পার্থক্য কি?
Jwan622

4
@ জওয়ান 22২২ লোকালহোস্ট ইন্টারফেসটি কেবলমাত্র ধারকটির ভিতরেই উপলব্ধ। 0.0.0.0 সমস্ত ইন্টারফেসের সাথে আবদ্ধ হয় b ইন্টারফেসগুলি বিভিন্ন নেটওয়ার্কের সাথে সংযুক্ত হয় (যাতে আপনার কাছে ওয়াইফাই, ল্যান ইত্যাদির জন্য একটি থাকতে পারে)
অ্যাড্রিয়ান মউত

-p 5000:5000আপনার docker runকমান্ড সহ পতাকাটি সহ আপনার ধারককে 5000 বন্দর বন্ড করার কথা মনে রাখবেন ।
টি লোচ

42

flaskপরিবর্তে কমান্ড ব্যবহার করার সময় app.run, আপনি --hostহোস্ট পরিবর্তন করার বিকল্পটি পাস করতে পারেন । ডকারে লাইনটি হ'ল:

CMD ["flask", "run", "--host", "0.0.0.0"]

বা

CMD flask run --host 0.0.0.0

4
এই সমাধানের জন্য আপনাকে অনেক ধন্যবাদ, আমারও একই সমস্যা, আপনি কি জানেন app.run(host="0.0.0.0") না যে কাজ না করার কারণ কী ? : আমিও এই প্রশ্নের জন্য পোস্ট করলে stackoverflow.com/q/53133350/3279996
xirururu

4
এই নোটটিতে, ব্যবহার না করার বিষয়টি নিশ্চিত করুন python run.py --host=0.0.0.0 । আমার নামকরণের সম্মেলনের কারণে এটি আমাকে একবারে একবারে পেয়ে যায়। এই কোডটি কাজ করতে উপস্থিত হবে তবে সার্ভারটি স্থানীয় হোস্টে চলবে।
ব্র্যাডেন হল্ট

4
এটি কি বিল্ট-ইন ফ্লাস্ক সার্ভারটি চালায় না, যা উত্পাদন পরিবেশের জন্য নয় ?
কোড_ড্রেড

এটি দুর্দান্ত, যে কোনও কারণেই প্রায় সকল ফ্লাস্ক-সহ-ডকার তথ্য ফ্লাস্ক সিএলআই ব্যবহার করতে ব্যর্থ হয়, যা আফাইক অ্যাপ্লিকেশন শুরু করার জন্য ফ্লাস্ক ১.০ উপায়।
জাচ ভ্যালেন্টা

4
এখানে 2020 সালে ফ্লাস্কের সাথে 1.1.1 app.run(host="0.0.0.0")ব্যর্থ এবং চ্যাম্পের CMD ["flask", "run", "--host", "0.0.0.0" ]মতো কাজ করে।
জো

5

আপনার পাইথন স্ক্রিপ্টে প্রথমে আপনাকে কোডটি পরিবর্তন করতে হবে

app.run()

প্রতি

app.run(host="0.0.0.0")

দ্বিতীয়ত, আপনার ডকার ফাইলে সর্বশেষ লাইনের মতো হওয়া উচিত

CMD ["flask", "run", "-h", "0.0.0.0", "-p", "5000"]

এবং হোস্ট মেশিনে যদি 0.0.0.0:5000কাজ না করে তবে আপনার চেষ্টা করা উচিতlocalhost:5000

দ্রষ্টব্য - সিএমডি কমান্ডটি যথাযথ হতে হবে। কারণ সিএমডি কমান্ড ধারক কার্যকর করার জন্য খেলাপি সরবরাহ করে।


3

আপনার ডকারের ধারকটির একাধিক নেটওয়ার্ক ইন্টারফেস রয়েছে। উদাহরণস্বরূপ, আমার ধারকটিতে নিম্নলিখিত রয়েছে:

$ 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

আপনি যদি চালনা করেন তবে docker network inspect bridgeদেখতে পাবেন যে আপনার ধারকটি উপরের আউটপুটটিতে দ্বিতীয় ইন্টারফেসের সাথে সেতুর সাথে সংযুক্ত রয়েছে। এই ডিফল্ট ব্রিজটি আপনার হোস্টের ডকার প্রক্রিয়াতেও সংযুক্ত।

সুতরাং আপনাকে কমান্ডটি চালাতে হবে:

CMD flask run --host 172.17.0.2

আপনার হোস্ট মেশিন থেকে একটি ডকার ধারক মধ্যে চলমান আপনার ফ্লাস্ক অ্যাপ্লিকেশন অ্যাক্সেস করতে। 172.17.0.2নির্দিষ্ট ধারার আইপি ঠিকানাটি আপনার ধারকটির যা-ই হোক তা দিয়ে প্রতিস্থাপন করুন ।


172.17.0.2পরিবর্তে ব্যবহার করে কোন সুবিধা 0.0.0.0? দুর্দান্ত উত্তর, আমি যুগ যুগ ধরে এটি খুঁজছিলাম!
ভয়ে

@ ভয়ে ইউজিং এর 0.0.0.0ফলে ফ্লাস্ককে সেই ধারকটিতে থাকা সমস্ত আইপি ঠিকানা শুনতে হবে । এটি নির্দিষ্ট হওয়া ভাল, কারণ আপনি অনিচ্ছাকৃতভাবে অন্যান্য নেটওয়ার্কগুলিতে সাইটটি খুলতে পারেন।
বার্ট

সবাই কেন এটি ব্যবহার করছে বলে মনে হচ্ছে? আপনার মতো আমারও ঠিক একই যুক্তি ছিল, তবে আমি কোনও অবাক হয়েছি যে কোনও সার্ভারের প্রকাশের প্রতিটি সংস্থান কীভাবে শোনার পরামর্শ দেয় 0.0.0.0। এটা কি হতে পারে যে এর বিপদগুলি ততটা তীব্র নয়? আপনার কি এমন কোনও উত্স থাকবে যেখানে আমি বিষয়টিকে ধরতে পারি?
ভয়ে

কারণ এটি দ্রুত এবং সহজ এবং লোকেরা নিজেরাই যাচাই বা গবেষণা না করে উত্তর অনুসন্ধানের জন্য এই জাতীয় সাইটগুলি পড়বে। ফ্লাস্ক কুইকস্টার্ট নথিতে উল্লেখ করা হয়েছে যে এটি একটি সুরক্ষা ঝুঁকিপূর্ণ এবং মিগুয়েল গ্রিনবার্গ টিউটোরিয়াল এমনকি বলেছে "তবে এটি প্রায়শই একটি খারাপ ধারণা" "
বার্ট

এটা খুব দরকারী, ধন্যবাদ বার্ট। যদি আমি এটি একটি বন্ধ ভার্চুয়াল বেসরকারী নেটওয়ার্কে চালিত করি? তাহলে কি 0.0.0.0 নিরাপদ থাকবে?
ভয়ে

2

অন্যান্য উত্তর তৈরি করতে:

আপনার দুটি কম্পিউটার রয়েছে তা কল্পনা করুন। প্রতিটি কম্পিউটারের একটি নেটওয়ার্ক ইন্টারফেস (ওয়াইফাই, বলুন) থাকে যা এটির সর্বজনীন আইপি। প্রতিটি কম্পিউটারের 127.0.0.1 এ একটি লুপব্যাক / লোকালহোস্ট ইন্টারফেস রয়েছে। এর অর্থ "কেবল এই কম্পিউটার"।

আপনি যদি কম্পিউটার A তে 127.0.0.1 এ তালিকাবদ্ধ থাকেন তবে কম্পিউটার বিতে চলাকালীন 127.0.0.1 এর মাধ্যমে আপনি এর সাথে সংযোগ স্থাপন করতে সক্ষম হবেন বলে আশা করবেন না সর্বোপরি, আপনি কম্পিউটার এ এর স্থানীয় , ব্যক্তিগত ঠিকানা শুনতে বলেছেন ।

ডকার একই রকম সেটআপ; প্রযুক্তিগতভাবে এটি একই কম্পিউটার, তবে লিনাক্স কার্নেল প্রতিটি ধারককে তার নিজস্ব বিচ্ছিন্ন নেটওয়ার্ক স্ট্যাকের সাথে চালানোর অনুমতি দিচ্ছে। সুতরাং একটি ধারকটিতে 127.0.0.1 আপনার হোস্টের চেয়ে আলাদা কম্পিউটারে 127.0.0.1 এর সমান। আপনি এটিতে সংযোগ করতে পারবেন না।

ডায়াগ্রামগুলির সাথে দীর্ঘতর সংস্করণ: https://pythonspeed.com/articles/docker-connection-refused/


0

আপনাকে 0.0.0.0ডকার ফাইলটিতে হোস্টটি পরিবর্তন করতে হবে। এটি একটি ন্যূনতম উদাহরণ

# Example of Dockerfile

FROM python:3.8.5-alpine3.12

WORKDIR /app

EXPOSE 5000
ENV FLASK_APP=app.py

COPY . /app
RUN pip install -r requirements.txt

ENTRYPOINT [ "flask"]
CMD [ "run", "--host", "0.0.0.0" ]

এবং ফাইল app.pyহয়

# app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello world"


if __name__ == "__main__":
    app.run()

তারপরে সংকলন করুন

docker build . -t deploy_flask

এবং সাথে চালানো

docker run -p 5000:5000 -t -i deploy_flask:latest

আপনি প্রতিক্রিয়া সঙ্গে পরীক্ষা করতে পারেন curl http://127.0.0.1:5000/ -v

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.