ডকারে বিচ্ছিন্ন অবস্থায় চলার সময় পাইথন অ্যাপটি কোনও কিছুই মুদ্রণ করে না


160

আমার কাছে পাইথন (২.7) অ্যাপ রয়েছে যা আমার ডকফাইলে শুরু হয়েছে:

CMD ["python","main.py"]

main.py শুরু হয়ে গেলে কিছু স্ট্রিং মুদ্রণ করে এবং পরে লুপে যায়:

print "App started"
while True:
    time.sleep(1)

আমি যতক্ষণ না এই-ই-ফ্ল্যাগ দিয়ে ধারকটি শুরু করি, যতক্ষণ না প্রত্যাশা অনুযায়ী সবকিছুই কাজ করে:

$ docker run --name=myapp -it myappimage
> App started

এবং আমি লগগুলির মাধ্যমে পরে একই আউটপুটটি দেখতে পাচ্ছি:

$ docker logs myapp
> App started

যদি আমি একই ধারকটি -d পতাকা দিয়ে চালানোর চেষ্টা করি তবে ধারকটি স্বাভাবিকভাবে শুরু হবে বলে মনে হচ্ছে, তবে আমি কোনও আউটপুট দেখতে পাচ্ছি না:

$ docker run --name=myapp -d myappimage
> b82db1120fee5f92c80000f30f6bdc84e068bafa32738ab7adb47e641b19b4d1
$ docker logs myapp
$ (empty)

তবে ধারকটি এখনও চলছে বলে মনে হচ্ছে;

$ docker ps
Container Status ...
myapp     up 4 minutes ... 

সংযুক্তি কিছু প্রদর্শন করে না:

$ docker attach --sig-proxy=false myapp
(working, no output)

কোন ধারণা কি ভুল হচ্ছে? পটভূমিতে দৌড়ালে "মুদ্রণ" আলাদা আচরণ করে?

ডকার সংস্করণ:

Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.2
Git commit (client): a8a31ef
OS/Arch (client): linux/arm
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.4.2
Git commit (server): a8a31ef

উত্তর:


265

শেষ পর্যন্ত আমি ডিকারে ডিমনাইজড চলাকালীন পাইথন আউটপুট দেখার একটি সমাধান পেয়েছি, গিটহাবের @ahmetlpbalkan এর জন্য ধন্যবাদ । আমি এখানে আরও রেফারেন্সের জন্য উত্তর দিচ্ছি:

এর সাথে আনফারড আউটপুট ব্যবহার করা হচ্ছে

CMD ["python","-u","main.py"]

পরিবর্তে

CMD ["python","main.py"]

সমস্যা সমাধান করে; আপনি আউটপুট (উভয়, stderr এবং stdout) এর মাধ্যমে দেখতে পারেন

docker logs myapp

এখন আছেন!


2
-আপনি আমার পক্ষে কাজ করে যাচ্ছেন বলে মনে হচ্ছে, তবে কোথাও কোনও ডকুমেন্টেশন রয়েছে যা এটি আসলে যা করে তার বর্ণনা দিয়ে?
লিটল গিক

7
অন্যান্য উত্তরের পরামর্শ অনুসারে পতাকাটি কাজ না করার ENV PYTHONUNBUFFERED=0ক্ষেত্রে আপনি পরিবেশের পরিবর্তনশীল সেট করার চেষ্টা করতে পারেন -u
ফারশিদ টি

1
এটি আমার সমস্যাও ছিল। আরও বিশদ ব্যাখ্যার জন্য দেখুন স্ট্যাকওভারফ্লো.com/
জোনাথন স্ট্রে


1
পাইথনুনবুউফারড = 0 টি সহায়তা করা নিরূপণ করার সময় পাইথন 3 এ স্বপ্নের মতো কাজ করে।
লেচ মিগডাল

71

আমার ক্ষেত্রে পাইথন চালানো -uকোনও পরিবর্তন হয়নি। কৌশলটি তবে PYTHONUNBUFFERED=0পরিবেশের পরিবর্তনশীল হিসাবে সেট করতে হবে :

docker run --name=myapp -e PYTHONUNBUFFERED=0 -d myappimage

6
আমার ক্ষেত্রে, যোগ করা -e PYTHONUNBUFFERED=0সাহায্য করে।
ডেভিড এনজি

1
ধন্যবাদ! আমি ঘন্টার পর ঘন্টা আমার দেওয়াল থেকে মাথা বেঁধে ছিলাম, এমনকি কাজ করার জন্য লগও পাইনি -u। আপনার সমাধানটি আমার জন্য
জঙ্গোর

2
আমি মনে করি এটি একটি আরও ভাল সমাধান, যে ফলাফলগুলি দেখতে আমাদের
ডকারের

2
এটি দুর্দান্ত ধন্যবাদ। এটি উল্লেখ করার মতো বিষয় যে এটি ডাইস পিথনুনবুফারড
এ স্টার

ডকার-রচনা ইন্টারফেসের জন্য কাজ করেছেন। কখনই অনুমান করতে পারতেন না
গভীরতরকরণ

24

আমার জন্য এটি একটি বৈশিষ্ট্য, কোনও বাগ নয়। সিউডো-টিটিওয়াই ব্যতীত অবিচ্ছিন্ন হওয়ার মতো কিছুই নেই। সুতরাং একটি সহজ সমাধান হ'ল আপনার চলমান ধারকটির জন্য সিউডো-টিটিওয়াই বরাদ্দ করা:

$ docker run -t ...

এটি প্রশ্নের উত্তর সরবরাহ করে না। কোনও লেখকের কাছ থেকে সমালোচনা বা স্পষ্টতার জন্য অনুরোধ জানাতে, তাদের পোস্টের নীচে একটি মন্তব্য দিন।
রাষ্ট্রপতি জেমস কে পোলক

@ জামেসকপল্ক, এখন কি এটি আরও ভাল?
পিটার সেন্না

স্ট্রাউট এবং স্টাডারের জন্য ডকারের জন্য সিউডো টিটিটি বরাদ্দ হওয়ার দরকার নেই
ম্যাট

3
tty: true
কমপোজ

15

এই নিবন্ধটি দেখুন যা আচরণের বিশদ কারণ ব্যাখ্যা করে:

বাফারিংয়ের জন্য সাধারণত তিনটি পদ্ধতি রয়েছে:

  • যদি কোনও ফাইল বর্ণনাকারী অসম্পূর্ণ হয় তবে কোনও বাফারিং ঘটে না, এবং ফাংশন কলগুলি যা ডেটা পড়তে বা লেখার সাথে সাথে উপস্থিত হয় (এবং অবরুদ্ধ হবে) will
  • যদি কোনও ফাইল বর্ণনাকারী পুরোপুরি বাফার হয় তবে একটি নির্দিষ্ট আকারের বাফার ব্যবহার করা হয়, এবং কলগুলি পড়তে বা লিখতে বাফার থেকে কেবল পড়তে বা লিখতে পারে। এটি পূরণ না হওয়া পর্যন্ত বাফার ফ্লাশ করা হয় না।
  • যদি কোনও ফাইল বর্ণনাকারী লাইন-বাফার হয় তবে বাফারিং নতুন লাইনের চরিত্রটি না হওয়া পর্যন্ত অপেক্ষা করে। সুতরাং কোনও \ n না দেখা পর্যন্ত ডেটা বাফার এবং বাফার করবে এবং তারপরে বাফার করা সমস্ত ডেটা সেই সময়টিতে ফ্লাশ করা হবে। বাস্তবে সাধারণত বাফারে সর্বোচ্চ আকার থাকে (ঠিক যেমন পুরো-বাফার ক্ষেত্রে) তাই নিয়মটি আসলে আরও অনেকটা "নতুন লাইনের চরিত্র না দেখা পর্যন্ত বাফার 4096 বাইট তথ্য না পাওয়া পর্যন্ত, যার মধ্যে প্রথম দেখা দেয় না" এর মতোই।

এবং জিএনইউ লিবিসি (গ্লিবসি) বাফারিংয়ের জন্য নিম্নলিখিত নিয়মগুলি ব্যবহার করে:

Stream               Type          Behavior
stdin                input         line-buffered
stdout (TTY)         output        line-buffered
stdout (not a TTY)   output        fully-buffered
stderr               output        unbuffered

সুতরাং, যদি ডকার ডকুমেন্ট-t থেকে ব্যবহার করা হয় , এটি একটি সিডো-টিটি বরাদ্দ করবে, তারপরে হয়ে যায় , এভাবে এক-লাইন আউটপুট দেখতে পেত।stdoutline-buffereddocker run --name=myapp -it myappimage

এবং যদি শুধু ব্যবহার -d, কোন TTY বরাদ্দ ছিল, তারপর, stdoutহয় fully-buffered, এক লাইন App startedনিশ্চয় বাফার ফ্লাশ করতে পারবেন না।

তারপর, ব্যবহার -dtকরার জন্য make stdout line bufferedবা অ্যাড -uপাইথন করা flush the bufferউপায় এটা ঠিক হয়।


8

যদি আপনি চলমান অবস্থায় আপনার মুদ্রণ আউটপুটটি আপনার ফ্লাস্ক আউটপুটটিতে যুক্ত করতে চান তবে docker-compose upনিম্নলিখিতটি আপনার ডকার রচনা ফাইলটিতে যুক্ত করুন।

web:
  environment:
    - PYTHONUNBUFFERED=1

https://docs.docker.com/compose/environment-variables/


6

আপনি বিচু্যত ছবিতে লগ দেখতে যদি আপনি পরিবর্তন করতে পারেন printথেকে logging

main.py:

import time
import logging
print "App started"
logging.warning("Log app started")
while True:
    time.sleep(1)

Dockerfile:

FROM python:2.7-stretch
ADD . /app
WORKDIR /app
CMD ["python","main.py"]

1
সুন্দর। টিপ: পাইথন 3 ব্যবহার করুন
অ্যাডহিগ

প্রশ্ন পাইথন 2 এ (প্রথম বন্ধনী ছাড়াই মুদ্রণ বিবরণী) সুতরাং এখানে 2 ব্যবহার করছি। যদিও পাইথন .6. on এ এটি ঠিক একই আচরণ, তাই একটি টিপের জন্য ধন্যবাদ;)
দ্য হগ

6

যেহেতু আমি এখনও এই উত্তরটি দেখিনি:

আপনি প্রিন্ট করার পরে আপনি স্ট্যাডআউট ফ্লাশ করতে পারেন:

import time

if __name__ == '__main__':
    while True:
        print('cleaner is up', flush=True)
        time.sleep(5)

1
এটি আমার পক্ষে নিখুঁতভাবে কাজ করেছে, নির্বোধ যে এটি থাকা দরকার, তবে এখন দুর্দান্ত কাজ করে।
জামেস্ক্যাম্পবেল


3

দ্রুত সমাধান হিসাবে এটি চেষ্টা করুন:

from __future__ import print_function
# some code
print("App started", file=sys.stderr)

আমি যখন একই সমস্যাগুলির মুখোমুখি হই তখন এটি আমার পক্ষে কাজ করে। তবে, সত্যি বলতে কী, কেন এই ত্রুটিটি ঘটে তা আমি জানি না।


বখশিশের জন্য ধন্যবাদ! আপনার সংস্করণ দিয়ে সমস্ত প্রিন্টগুলি প্রতিস্থাপনের চেষ্টা করা হয়েছে, দুর্ভাগ্যক্রমে এটি আমার পক্ষে কার্যকর হয়নি, ডকার লগের মাধ্যমে এখনও কোনও আউটপুট পেতে পারে না (সিএস.এসটিডার / সিএস.স্টডআউটের মধ্যে পরিবর্তনের কোনও দৃশ্যমান ফলাফল নেই)। এটি কি ডকার বাগ?
jpdus

আমার উত্তরটি দেখুন , কারণটি হল: স্ট্যাডারটি ভারসাম্যহীন ছিল, যাতে আপনি এটি সমাধান সহ সমাধান করতে পারেন।
অনলাইনে


0

সাধারণত, আমরা এটিকে একটি নির্দিষ্ট ফাইলে পুনর্নির্দেশ করি (হোস্ট থেকে একটি ভলিউম মাউন্ট করে এবং সেই ফাইলটিতে এটি লিখে)।

-T ব্যবহার করে একটি টিটি যোগ করাও ঠিক। আপনার এটি ডকার লগে নিতে হবে।

বড় লগ আউটপুট ব্যবহার করে, বাফারকে লগ-ইন না করে সব সংরক্ষণ করে আমার কোনও সমস্যা নেই।


-1

আপনি যদি ব্যবহার না করে থাকেন docker-composeএবং dockerপরিবর্তে কেবল সাধারণ হন, আপনি এটি আপনার Dockerfileফ্ল্যাশ অ্যাপ্লিকেশনটিকে হোস্টিংয়ের সাথে যুক্ত করতে পারেন

ARG FLASK_ENV="production"
ENV FLASK_ENV="${FLASK_ENV}" \
    PYTHONUNBUFFERED="true"

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