40-წუთიანი სამუშაო სესია კონტეინერებზე — პრობლემიდან "ჩემს მანქანაზე მუშაობს", იმიჯებზე, Dockerfile-ებსა და შრეებზე, ვოლუმებზე, ქსელსა და Compose-ზე გავლით, შემდეგ ინსტრუმენტებზე, რომელთა შორისაც აირჩევთ, და ბოლოს რეალურ ცუდი → კარგი აწყობამდე, რომელიც შეგიძლიათ დააკოპიროთ.
კოდი იშვიათად ტყდება მარტო — ის იმიტომ ტყდება, რომ გარშემო მანქანა სხვაა: Node-ის სხვა ვერსია, აკლია სისტემური ბიბლიოთეკა, კონფიგი, რომელიც მხოლოდ ვიღაცის ლეპტოპზე არსებობს. კონტეინერები ამას ასწორებენ იმით, რომ გარემოს კოდთან ერთად აგზავნიან.
გარემო, სადაც ერთნაირად უნდა იქცეოდეს: dev, CI, prod.
არტეფაქტი ყველასთვის — იმიჯი, რომელსაც ერთხელ აგებთ.
გაშვება, არა წუთები — კონტეინერები ჰოსტის ბირთვს იზიარებენ.
და არა GB — სრული სტუმარი OS არ იგზავნება.
VM-ები ავირტუალებენ აპარატურას (თითოეულს სრული OS აქვს); კონტეინერები ავირტუალებენ OS-ს (ერთი საერთო ბირთვი) — ამიტომ MB-ებში იგზავნება და მილიწამებში ეშვება.
ეს ერთი განსხვავება რომ გაიგოთ, დანარჩენი Docker თავისით ჯდება ადგილზე. კავშირი ზუსტად ისეთია, როგორიც კლასი → ობიექტი: შაბლონს ერთხელ აგებთ, შემდეგ კი იმდენ ცოცხალ ასლს უშვებთ, რამდენიც გინდათ.
docker build Dockerfile-ს იმიჯად აქცევს.docker pull უკვე აგებულ იმიჯს რეგისტრიდან ჩამოტვირთავს (მაგ. Docker Hub).docker run იმიჯიდან კონტეინერს უშვებს.docker ps ჩამოთვლის მომუშავე კონტეინერებს; stop / rm აჩერებს და შლის მათ.docker builddocker pulldocker rundocker psdocker stopdocker rmკონტეინერები იზიარებენ იმიჯის შრეებს, რომლებიც read-only-ა; თითოეული ზემოდან საკუთარ თხელ ჩაწერად შრეს ამატებს.
კონტეინერები ერთჯერად და უცვლელ ერთეულებად მიიჩნიეთ: მომუშავეს არასოდეს დაუწყოთ ჩასწორება. თუ ცვლილება გჭირდებათ, შეცვალეთ იმიჯი და გაუშვით ახალი კონტეინერი. პირუტყვი და არა pet-ები — ავადმყოფ კონტეინერს ხელით არ მკურნალობთ; მას განახლებული იმიჯიდან აგებული ახლით ცვლით.
Docker იმიჯს ისე აგებს, რომ თქვენს Dockerfile-ს ზემოდან ქვემოთ ასრულებს და ყოველ ინსტრუქციას შრედ ქეშირებს. ამ ქეშის გაგება არის განსხვავება 2-წამიან და 5-წუთიან ხელახალ აგებას შორის — და 1.2GB-იან და 90MB-იან იმიჯს შორის.
FROM, COPY, RUN…) ერთ უცვლელ შრეს ქმნის. Docker-ი შრის ქეშს მანამ იყენებს ხელახლა, სანამ ეს ნაბიჯი და ყველაფერი მის ზემოთ უცვლელია — ამიტომ თანმიმდევრობას უზარმაზარი მნიშვნელობა აქვს.FROM — საბაზო იმიჯი, საიდანაც იწყებთ.WORKDIR — სამუშაო დირექტორიის დაყენება.COPY — ფაილების კოპირება თქვენი კონტექსტიდან იმიჯში.RUN — ბრძანების შესრულება აგების დროს (დამოკიდებულებების დაყენება, კომპილაცია).EXPOSE — დოკუმენტირება, რომელ პორტს უსმენს აპლიკაცია.CMD — ნაგულისხმევი ბრძანება, რომელიც გაშვების დროს სრულდება. დაწერეთ სიად — ["node","server.js"], ეს არის exec ფორმა — რომ როცა Docker კონტეინერს აჩერებს, სიგნალი "გთხოვ, გაითიშე" პირდაპირ თქვენს აპლიკაციას მიუვიდეს და მან სუფთად დაასრულოს. უბრალო სტრიქონის shell ფორმა (node server.js) თქვენს აპლიკაციას shell-ის უკან მალავს, ამიტომ ის უხეშად კვდება.deps წყაროზე ადრე კოპირდება: შეცვლით როუტს და მხოლოდ ბოლო ორი შრე აიგება ხელახლა.
ქეშის მოხვედრა პირველ შეცვლილ შრეზე ჩერდება; მის ქვემოთ ყველაფერი ხელახლა იგება. ზემოთ ის დადეთ, რაც ყველაზე იშვიათად იცვლება.
ერთ ეტაპზე სრული ინსტრუმენტებით დააკომპილირეთ, შემდეგ კი მხოლოდ შედეგი გადაიტანეთ პაწაწინა runtime იმიჯში. თქვენი კომპილატორი, dev დამოკიდებულებები და წყარო პროდაქშენამდე არასოდეს აღწევს.
თითქოს სრულ სამზარეულოში ამზადებთ, შემდეგ კი მხოლოდ გაწყობილ კერძს გადასცემთ — და არა ქვაბებსა და ტაფებს.
აგების კონტექსტი არის ყველაფერი, რასაც Docker აგებამდე ატვირთავს. .dockerignore გამორიცხავს იმას, რაც იმიჯს ასუქებს და ქეშს აფუჭებს — და საიდუმლოებებს შემოპარვის საშუალებას არ აძლევს.
თითქოს .gitignore თქვენი იმიჯისთვის — პატარა, სწრაფი და უსაფრთხო აგება.
იმიჯის თავზე მდებარე თხელი ჩაწერადი შრე კონტეინერთან ერთად კვდება. წაშალეთ კონტეინერი — ან ხელახლა დაადეპლოეთ ახალი იმიჯი — და შიგნით ჩაწერილი ყველაფერი ქრება. მონაცემთა ბაზებისთვის, ატვირთვებისა და მდგომარეობისთვის გჭირდებათ საცავი, რომელიც პროცესს გადაურჩება.
ჩანაწერები დამაუნთებულ გზაზე ვოლუმში ხვდება და არა ერთჯერად ჩაწერად შრეში — ამიტომ ისინი კონტეინერს გადაურჩება.
საცავის ადგილს Docker ფლობს. ნაგულისხმევი არჩევანი პროდაქშენის მონაცემებისთვის — ბაზები, ატვირთვები. პორტატულია, სარეზერვო ასლს იღებს და ჰოსტის გზაზე მიბმული არაა.
თქვენს მანქანაზე არსებულ ნამდვილ დირექტორიას კონტეინერში ასახავს. იდეალურია ლოკალური დეველოპმენტისთვის — წყაროს ჰოსტზე ცვლით, კონტეინერი მას მაშინვე ხედავს (hot reload).
ინახება RAM-ში, არასოდეს დისკზე, და ქრება კონტეინერის გაჩერებისას. საიდუმლოებისთვის ან დროებითი მონაცემებისთვის, რომელთა შენახვაც შეგნებულად არ გინდათ.
თითქოს საერთო მაგიდების ოფისი: მაგიდა (კონტეინერი) ყოველ ღამე იწმინდება, მაგრამ თქვენი კარადა (ვოლუმი) ნივთებს დღეებს შორის ინახავს.
თავიდან ორი კითხვა აბნევს ყველას: როგორ აღწევს გარე სამყარო კონტეინერამდე? (გამოაქვეყნეთ პორტი) და როგორ აღწევენ კონტეინერები ერთმანეთამდე? (დააყენეთ ისინი ერთსა და იმავე ქსელში და სერვისების სახელები გამოიყენეთ). ეს რომ გაიგოთ, Compose თავისთავად ცხადი ხდება.
-p HOST:CONTAINER-ით თქვენს მანქანაზე არსებულ პორტს კონტეინერის შიგნით არსებულზე გადამისამართებს. მომხმარებლის შექმნილი ქსელი არის პრივატული ხიდი, რომელიც მასზე მყოფ კონტეინერებს ერთმანეთის სახელით პოვნის საშუალებას აძლევს, Docker-ის ჩაშენებული DNS-ით — IP-ების გარეშე, --link-ის გარეშე.გარედან → შიგნით გამოქვეყნებული პორტით; შიგნიდან → შიგნით სერვისის სახელით db საერთო ქსელში.
-p 8080:3000localhost:8080 თქვენს მანქანაზე ახლა აღწევს აპლიკაციამდე, რომელიც შიგნით :3000-ზეა მიბმული.-p-ის გარეშე პორტი ხელმისაწვდომია ქსელში სხვა კონტეინერებისთვის, მაგრამ არა ჰოსტისთვის.რეალური აპლიკაციები ერთი კონტეინერი არაა — ეს არის ვებსერვისი, მონაცემთა ბაზა, შესაძლოა ქეშიც და რიგიც, ერთმანეთთან შეერთებული. ყოველ ჯერზე გრძელი docker run-ების სწორი თანმიმდევრობით აკრეფა შეცდომების რეცეპტია. Compose-ი სტეკს დეკლარაციულს ხდის.
docker compose up ქმნის ქსელს და ყველაფერს უშვებს. ეს ფაილი თავად არის დოკუმენტაცია.ყველაფერი 2–5 სექციიდან ერთ ადგილას: იმიჯი, პორტი, env, ვოლუმი, დამოკიდებულებების თანმიმდევრობა.
web სახელით აღწევს db-მდე, კონფიგის გარეშე.depends_on + healthcheck უშვებს ბაზას და ელოდება, სანამ ის ნამდვილად მზად იქნება web-ის გაშვებამდე.volume Postgres-ის მონაცემებს down/up ციკლებს შორის ინახავს.build: . web-ს თქვენი Dockerfile-იდან აგებს; image: ბაზას მზა სახით ჩამოიტანს.compose up -dcompose downcompose logs -fcompose pscompose buildDocker-მა კონტეინერები გაავრცელა, მაგრამ ყოველ ნაბიჯზე — სად ინახავთ იმიჯებს, რითი აგებთ მათ, რომელი ბაზიდან იწყებთ და როგორ უშვებთ მათ მასშტაბურად — რეალური ალტერნატივებია. აი, წამყვანები: თითოეულს ერთი გულწრფელი დადებითი და უარყოფითი მხარით, და არჩევის მოკლე წესით.
FROM შრე, რომელზეც ყველაფერი დანარჩენი ეწყობა. ორკესტრატორი თქვენს კონტეინერებს ერთ ან ბევრ მანქანაზე უშვებს.პაიპლაინი, რომელიც ქვემოთ ყველა ინსტრუმენტს აქვს საერთო: ააგე იმიჯი, ატვირთე რეგისტრში, ჩამოიტანე და გაუშვი სხვაგან. ვენდორები უბრალოდ ყოველ ისარზე იცვლება.
docker pull პირველად იყურება, ამიტომ თითქმის ყოველი საბაზო იმიჯი ერთი ბრძანების დაშორებითაა.საუკეთესოა საჯარო იმიჯებისა და სწავლისთვის → Hub; უკვე GitHub-ზე ცხოვრობთ → GHCR; AWS-ზე მუშაობთ და ყველაფერი პრივატული გინდათ → ECR.
docker-ს თითქმის ბრძანება-ბრძანებით იმეორებს.საუკეთესოა უმეტესობისთვის → Docker; უსაფრთხოება ან root-ის გარეშე გარემო → Podman; კლასტერში ან პაიპლაინში აგება → Kaniko / Buildpacks.
FROM, საიდანაც იწყებთexec-ით შეხვიდეთ, ამიტომ დებაგი რთულდება; აგება სხვაგან უნდა მოახდინოთ და შედეგი შიგნით გადმოაკოპიროთ (მრავალეტაპიანი).საუკეთესოა სწრაფი ლოკალური ცდებისთვის → სრული; ყოველდღიური პროდაქშენისთვის → slim; ჩაკეტილი პროდაქშენისთვის → distroless.
საუკეთესოა დეველოპმენტი და ერთი სერვერი → Compose; ბევრი სერვერი და პლატფორმის გუნდი → Kubernetes; მასშტაბი საოპერაციო ტვირთის გარეშე → მართული სერვისი.
გულწრფელი ნაგულისხმევი არჩევანი უმეტესი გუნდისთვის: Docker-ი ასაგებად, მსუბუქი ბაზა, თქვენი პლატფორმის რეგისტრი და Compose-ი მანამ, სანამ ერთი მანქანა ნამდვილად აღარ იქნება საკმარისი. მძიმე ვარიანტებს მაშინ მიმართეთ, როცა რეალური საჭიროება გაჩნდება.
ყველაფერი ერთ ადგილას: ერთი და იგივე ვებსერვისი, ჯერ ისე გაკეთებული, რომ მოგკბენთ, შემდეგ კი ისე, რომ გაუძლებს. ბოლოს — ხუთი წესი, რომელსაც თან წაიღებთ.
.env და პროცესი, რომელიც დეპლოიზე SIGTERM-ს უგულებელყოფს..dockerignore არ არის, მძიმე ბაზა, shell-ფორმის CMD.CMD, საიდუმლოებები გარეთ დატოვებული .dockerignore-ით.compose.yaml ბაზისთვის + ვოლუმისთვის + ქსელისთვის, რომ compose up-მა მთელი სტეკი ერთად ააშვას..dockerignore."ააგე ერთხელ, გაუშვი ყველგან — რადგან გარემო კოდთან ერთად იგზავნება."
— კონტეინერების მთელი აზრი
ხუთი სწრაფი კითხვა იმიჯებზე, შრეებზე, ვოლუმებზე, ქსელსა და Compose-ზე — მყისიერი პასუხი, ავტორიზაციის გარეშე.
ნავიგაცია ← → ან სქროლით · უკან ბიბლიოთეკაში