RE:NODE

VDS13 წუთის საკითხავი

Docker Compose პატარა stack-ებისთვის: ერთი ფაილი, სამი სერვისი

გაუშვი proxy, აპლიკაცია და ბაზა ერთი compose ფაილიდან: ქსელები, volume-ები, env ფაილები, healthcheck-ები, განახლებები და უკან დაბრუნება ერთ სერვერზე.

0 მკითხველი

Compose არის ტექსტური ფაილი, რომელიც რამდენიმე კონტეინერსა და მათ შორის კავშირებს აღწერს, და ბრძანება, რომელიც რეალობას ფაილს ამთხვევს. ერთ სერვერზე ეს იმაზე მეტს ღირს, ვიდრე ჟღერს. მის გარეშე სამკონტეინერიანი stack სამი docker run ხაზია ოცი flag-ით ერთმანეთს შორის, რომელიც ექვსი კვირის შემდეგ არასწორად გახსოვს. მასთან ერთად მთელი საქმე docker compose up -d-ია, კონფიგურაცია ფაილია, რომელიც git-ში შეგიძლია შეინახო, და stack-ის ახალ მანქანაზე აღდგენა git clone და ერთი ბრძანებაა.

Compose არ არის scheduler. ის კონტეინერს სხვა ჰოსტზე არ გადაიტანს, არ გადატვირთავს იმას, რაც არაჯანსაღი გახდა, და შეფერხების შესახებ აზრი არ აქვს. ერთ VDS-ზე ეს არაფერს გაკარგვინებს, რადგან ჰოსტი ერთია და ალტერნატივა shell სკრიპტი იყო. ეს პოსტი რეალისტურ stack-ს აგებს - reverse proxy, აპლიკაცია და PostgreSQL ბაზა - და შემდეგ იმ ნაწილებს განიხილავს, რომლებიც წყვეტს, გადარჩება თუ არა ის ერთ წელს: სად არის მონაცემები, რას წაშლის down, როგორ ხვდება საიდუმლოებები შიგნით და რა უნდა გააკეთო, როცა ის არ ადგება.

რა არის Compose და რა ფაილს კითხულობს#

Compose v2 plugin-ია და გამოიძახება როგორც docker compose, გამოტოვებით ორ სიტყვას შორის. ძველი Python-ის docker-compose დეფისით ცალკე, გაუქმებული პროგრამაა; თუ tutorial დეფისს იყენებს, ის მიმდინარე ინსტრუმენტებზე ადრეა, თუმცა ფაილის ფორმატი ძირითადად იგივეა.

Compose ეძებს, ამ თანმიმდევრობით: compose.yaml, compose.yml, docker-compose.yaml, docker-compose.yml. პირველი სახელი მიმდინარე კონვენციაა, ბოლო კი ის, რომელიც ყველას აქვს. ორივე მუშაობს. რაც აღარ მუშაობს სასარგებლოდ, ძველი ფაილების თავში მდგარი version: "3.8" ხაზია - Compose v2-ში ის მოძველებულია, უგულებელყოფილია და გაფრთხილებას იძლევა. წაშალე.

ერთი ცნება უნდა გაიგო, სანამ ფაილს აზრი ექნება: project. Compose ყველაფერს, რასაც ქმნის, project-ის სახელით არქმევს, რომელიც ნაგულისხმევად დირექტორიის სახელია. /srv/notes-ში მდებარე compose.yaml ქმნის კონტეინერებს notes-app-1 და notes-db-1, ქსელს notes_default და volume-ს notes_dbdata. ორ დირექტორიაში ორი project ერთმანეთს არ ეჯახება. ამიტომაც შეიძლება დირექტორიის გადატანამ ან გადარქმევამ Compose-ს უცებ ეფიქრებინოს, რომ საქმე აქვს სრულიად ახალ stack-თან volume-ების გარეშე - თუ დირექტორია შეიძლება გადაადგილდეს, სახელი დააფიქსირე უმაღლესი დონის name: გასაღებით.

ერთი ფაილი, სამი სერვისი#

აი stack, რომელიც მართლა მუშაობს: Caddy წინ TLS-ისთვის, Node აპლიკაცია და PostgreSQL ორივეს უკან.

compose.yaml
name: notesservices:  proxy:    image: caddy:2    restart: unless-stopped    ports:      - "80:80"      - "443:443"    volumes:      - ./Caddyfile:/etc/caddy/Caddyfile:ro      - caddy_data:/data      - caddy_config:/config    depends_on:      - app  app:    image: ghcr.io/example/notes:1.4.2    restart: unless-stopped    env_file:      - app.env    environment:      DATABASE_URL: postgres://notes:${DB_PASSWORD}@db:5432/notes      NODE_ENV: production    depends_on:      db:        condition: service_healthy  db:    image: postgres:17    restart: unless-stopped    environment:      POSTGRES_USER: notes      POSTGRES_PASSWORD: ${DB_PASSWORD}      POSTGRES_DB: notes    volumes:      - dbdata:/var/lib/postgresql/data    healthcheck:      test: ["CMD-SHELL", "pg_isready -U notes -d notes"]      interval: 10s      timeout: 5s      retries: 5      start_period: 30svolumes:  dbdata:  caddy_data:  caddy_config:

და proxy-ის კონფიგურაცია, რომელსაც ის mount-ავს და რომელიც სამი ხაზია, რადგან Caddy სერტიფიკატს თავად იღებს და ანახლებს, როგორც კი DNS სახელი მანქანას მიუთითებს:

Caddyfile
notes.example.com {    encode gzip    reverse_proxy app:3000}

შეამჩნიე, რა აკლია. აპლიკაციას ports: ჩანაწერი არ აქვს და ბაზასაც არა. არც ერთი მათგანი მანქანის გარედან საერთოდ მიუწვდომელია. მხოლოდ proxy აქვეყნებს რაღაცას და ის ორ პორტს აქვეყნებს, რომელსაც ინტერნეტი უკვე მოელის.

TLS on 443http://app:3000TCP 5432ინტერნეტიპორტები 80 და 443Caddyაქვეყნებს 80-სა და 443-სNode აპლიკაციაუსმენს :3000-ზეPostgreSQLvolume dbdata
ერთი საჯარო კარი ორი პირადი სერვისის წინ

ქსელი და რატომ აქვეყნებს პორტს მხოლოდ proxy#

Compose project-ზე ერთ ქსელს ქმნის და ყველა სერვისს მასზე აერთებს. ამ ქსელში Docker-ის ჩაშენებული DNS თითოეულ სერვისის სახელს მის კონტეინერზე აჭრის, ამიტომ app ბაზას hostname-ით db პორტზე 5432 ყოველგვარი კონფიგურაციის გარეშე უკავშირდება, ხოლო proxy აპლიკაციას app:3000-ზე. არაფერს არ სჭირდება IP მისამართის ცოდნა და მისამართები ყოველ ხელახლა შექმნაზე მაინც იცვლება.

მნიშვნელოვანი შედეგი: ერთსა და იმავე Compose ქსელზე მყოფ სერვისებს შორის პორტები უკვე ღიაა. ports: არ არის იმისთვის, რომ კონტეინერებმა ერთმანეთს ელაპარაკონ; ის არის ჰოსტიდან კონტეინერში ხვრელის გაჭრისთვის. ყოველი ports: ჩანაწერი, რომელსაც დაამატებ, ახალი საჯარო მსმენელია, ამიტომ დაამატე ისინი მხოლოდ წინა კარისთვის.

ეს ასევე წყვეტს პრობლემას, რომელშიც ხალხი პირველად ებმევა. გამოქვეყნებული პორტი UFW-ს გვერდს უვლის - ports: - "5432:5432" ბაზაზე PostgreSQL-ს ინტერნეტიდან მისაწვდომს ხდის ნაგულისხმევი deny firewall-ის მიუხედავად, რადგან პაკეტი ჰოსტზე მიწოდების ნაცვლად კონტეინერს გადაეცემა. სრული მექანიზმი UFW firewall-ის გზამკვლევშია, უფრო მოკლე ვერსია კი Docker VDS-ზე. თუ debug-ისთვის პორტის გამოქვეყნება აუცილებელია, გამოაქვეყნე loopback-ზე - "127.0.0.1:5432:5432" - და მიაღწიე SSH tunnel-ით.

თუ Caddy-ს nginx-ს ამჯობინებ, იგივე ფორმა მოქმედებს უფრო გრძელი კონფიგურაციის ფაილით, იმ header ხაზების ჩათვლით, რომლებიც proxy-ის უკან მდგარ აპლიკაციას კლიენტის რეალურად დასანახად სჭირდება. nginx reverse proxy-ის გზამკვლევს ეს server block აქვს, ხოლო რას აკეთებს reverse proxy განმარტავს, საერთოდ რატომ არსებობს X-Forwarded-For.

გარემოს ცვლადები და env ფაილის ორი სახეობა#

ეს თითქმის ყველას აბნევს, რადგან არსებობს ორი მექანიზმი მსგავსი სახელებით, რომლებიც სხვადასხვა საქმეს აკეთებენ.

`.env` ფაილი project-ის დირექტორიაში Compose-ს თვითონ კითხულობს, რაიმეს გაშვებამდე, და მისი მნიშვნელობები compose.yaml-ის შიგნით ${VAR} ადგილსამყოფლებს ანაცვლებს. ის ფაილს აკონფიგურირებს და არა კონტეინერებს. თუ .env შეიცავს DB_PASSWORD=hunter2-ს, ${DB_PASSWORD} compose ფაილში ამ მნიშვნელობად იქცევა.

`env_file:` სერვისზე KEY=value ხაზების ფაილს ამ კონტეინერს გარემოს ცვლადებად გადასცემს. Compose მის შიგნით არასოდეს იხედება. აქ არის აპლიკაციის კონფიგურაციის ადგილი.

.env - Compose კითხულობს, compose.yaml-ში ჩაისმება
DB_PASSWORD=a-long-random-stringAPP_TAG=1.4.2
app.env - გადაეცემა app კონტეინერს
SESSION_SECRET=another-long-random-stringSMTP_HOST=smtp.example.comLOG_LEVEL=info

ორივე ფაილი საიდუმლოებას შეიცავს, ამიტომ ორივეს chmod 600 უნდა და ორივე .gitignore-ში უნდა იყოს, commit-ში კი app.env.example, რომელიც გასაღებებს ჩამოთვლის მნიშვნელობების გარეშე. environment:-ში დაყენებული ცვლადები env_file:-დან მოსულს გადაფარავს, რაც წესია, რომელიც უნდა გახსოვდეს, როცა მნიშვნელობა იდუმალებით არ არის ის, რასაც ფაილი ამბობს.

სანამ აპლიკაციას დაადანაშაულებ, შეამოწმე, რა გადაწყვიტა Compose-მა რეალურად:

bash
$ docker compose config$ docker compose config --services

docker compose config სრულად გაერთიანებულ და ინტერპოლირებულ ფაილს ბეჭდავს. ცარიელი მნიშვნელობა იქ, სადაც პაროლს ელოდი, ნიშნავს, რომ .env ფაილი იქ არ არის, სადაც Compose ეძებს, რაც თითქმის ყოველთვის იმით ხდება, რომ ბრძანება არასწორი დირექტორიიდან გაუშვი. გარემოს ცვლადები და საიდუმლოებები უფრო ფართო კითხვას განიხილავს - რა უნდა იყოს საერთოდ გარემოს ცვლადი.

ყველაფრისთვის, რაც პროცესის გარემოში არ გინდა, Compose ფაილზე დაფუძნებულ secrets-ს უჭერს მხარს: secrets: ბლოკი ჰოსტის ფაილს ასახელებს, სერვისი კი მას read-only რეჟიმში იღებს /run/secrets/<name>-ზე. ბევრი image თავისი პაროლის ცვლადის ..._FILE ვარიანტს იღებს სწორედ იმისთვის, რომ იქ მიუთითო.

Volume-ები: რა უნდა გადარჩეს down-ს#

ზემოთ მაგალითში ყველა სერვისი ერთჯერადია, გარდა იმისა, რაც დასახელებულ volume-ებშია. ეს განზრახ არის და ესაა გონებრივი მოდელი, რომელიც უნდა შეინარჩუნო: კონტეინერები საქონელია, volume-ები - ჯოგი.

გზასახეობარატომ
dbdata:/var/lib/postgresql/datanamed volumeბაზა. მისი დაკარგვა ყველაფერს კარგავს
caddy_data:/datanamed volumeგაცემული სერტიფიკატები და ACME ანგარიშის გასაღებები
./Caddyfile:/etc/caddy/Caddyfile:robind mountშენ ცვლი, ამიტომ repo-ში შეინახე

caddy_data ადვილი დასავიწყებელია და შემაწუხებელი დასაკარგავი: მის გარეშე proxy-ის ყოველი ხელახლა შექმნა სერტიფიკატებს თავიდან ითხოვს, ხოლო სერტიფიცირების ორგანოები გაცემას დომენზე კვირაში ზღუდავენ. რამდენიმე დაუდევარი აღდგენა და დღეების განმავლობაში ვეღარ მიიღებ ახალ სერტიფიკატს დომენზე, რომელიც რეალურ ტრაფიკს ემსახურება.

Backup არის ბაზის დამპი განრიგით და არა მონაცემთა დირექტორიის ასლი, სანამ მასში წერენ:

bash
$ docker compose exec -T db pg_dump -U notes -Fc notes > /srv/backups/notes-$(date +%F).dump$ docker compose exec -T db psql -U notes -d notes < /srv/backups/restore-test.sql

-T მნიშვნელოვანია: მის გარეშე exec pseudo-terminal-ს გამოყოფს და გადამისამართებულ ბინარულ დამპს ხაზის დასასრულის გადათარგმნით აფუჭებს. პირველი ხაზი ჩასვი cron job-ში ან systemd timer-ში, შედეგები მანქანიდან გარეთ გადაიტანე და შემდეგ ერთი აღადგინე სადმე უწყინარ ადგილას, რომ დაამტკიცო, რომ ფაილი ნამდვილია. backup, რომელიც არავის აღუდგენია, ჰიპოთეზაა - ბაზის backup-ები და აღდგენები უფრო გრძელი არგუმენტია.

depends_on, healthcheck-ები და start-ის თანმიმდევრობა#

depends_on მოკლე ფორმით მხოლოდ start-ის თანმიმდევრობას განაგებს. ის ელოდება, სანამ კონტეინერი შეიქმნება და გაეშვება და არა იმას, რომ მის შიგნით პროგრამა პასუხისთვის მზად იყოს. PostgreSQL კონტეინერს პირველ გაშვებაზე ინიციალიზაციისთვის რამდენიმე წამი სჭირდება, ამიტომ აპლიკაცია, რომელიც ჩატვირთვისას უკავშირდება, ბაზაზე ჩავარდება, რომელიც ტექნიკურად მუშაობს.

გრძელი ფორმა ამას healthcheck-ის ლოდინით აგვარებს:

yaml
    depends_on:      db:        condition: service_healthy

რისთვისაც ბაზამ ერთი უნდა განსაზღვროს, როგორც მაგალითში pg_isready-ით. ოთხი პარამეტრი გასაგებია: interval ამბობს, რამდენად ხშირად სრულდება შემოწმება, timeout - რამდენ ხანს შეიძლება გაგრძელდეს ერთი მცდელობა, retries - რამდენი მიმდევრობითი წარუმატებლობა ხდის მას არაჯანსაღად, ხოლო start_period არის საწყისი საშეღავათო ფანჯარა, რომლის დროსაც წარუმატებლობები არ ითვლება. ბაზა, რომელიც პირველ start-ზე დიდ დამპს აღადგენს, გულუხვ start_period-ს საჭიროებს, თორემ არაჯანსაღად გამოცხადდება მაშინ, როცა ზუსტად იმას აკეთებს, რასაც უნდა.

ხელმისაწვდომი სამი პირობაა service_started (მოკლე ფორმის ნაგულისხმევი ქცევა), service_healthy და service_completed_successfully, რომელთაგან ბოლო არის ის, რითაც migration job-ს აპლიკაციამდე უშვებ.

ამ ყველაფრის მიუხედავად, დაწერე აპლიკაცია ისე, რომ ბაზასთან კავშირი მოკლე backoff-ით გაიმეოროს. start-ის თანმიმდევრობა პირველ ოცდაათ წამს წყვეტს; ბაზის გადატვირთვა დილის სამ საათზე მეორე შემთხვევაა, ხოლო სერვისი, რომელიც სამუდამოდ გადის იმიტომ, რომ კავშირი ერთხელ ჩავარდა, სერვისია, რომელსაც დილის სამ საათზე ადამიანი სჭირდება. Migration-ები შეფერხების გარეშე იმავე პრობლემის სქემის მხარეს ფარავს.

ბრძანებები, რომლებსაც რეალურად აკრეფ#

bash
$ docker compose up -d              # create or update everything, detached$ docker compose ps                 # what is running, and its health$ docker compose logs -f --tail 100 app$ docker compose exec app sh        # a shell in the running container$ docker compose run --rm app npm run migrate$ docker compose restart app        # restart without recreating$ docker compose stop               # stop, keep everything$ docker compose down               # remove containers and network

up -d იდემპოტენტურია და თითქმის ყველაფრისთვის ის ბრძანებაა, რომელსაც იყენებ. ის ფაილს რეალობას ადარებს და ხელახლა მხოლოდ იმ სერვისებს ქმნის, რომელთა განსაზღვრებაც შეიცვალა, რაც ნიშნავს, რომ ერთი სერვისის image tag-ის შეცვლა და up -d მხოლოდ მას ეხება და დანარჩენებს გაშვებულს ტოვებს.

განსხვავება exec-სა და run-ს შორის ხალხს აბნევს: exec უკვე გაშვებულ კონტეინერში შედის, run კი იმავე განსაზღვრებიდან ახალს უშვებს. გამოიყენე run --rm ერთჯერადი დავალებებისთვის, მაგალითად migration ან management ბრძანება, და exec რაღაცის ცოცხლად სანახავად.

კიდევ ორი, რაც ღირს ცოდნად. docker compose pull უფრო ახალ image-ებს ჩამოტვირთავს გაშვებული stack-ის შეხების გარეშე, ასე რომ შეგიძლია ჩამოტვირთო მოსახერხებელ მომენტში და გადართო უფრო წყნარში. და docker compose --profile debug up -d უშვებს სერვისებს, რომლებიც profiles: გასაღებით არის მონიშნული, რითაც admin ინსტრუმენტს ან ბაზის GUI-ს იმავე ფაილში ინახავ და მუდმივად არ უშვებ.

განახლება, უკან დაბრუნება და გამოშვება, რომელსაც ინანებ#

განახლება ორი ბრძანებაა და ფაილში მდგარი tag არის ის, რაც მათ უსაფრთხოს ხდის:

bash
$ docker compose pull app$ docker compose up -d app

რადგან image-ები 1.4.2-ზეა დაფიქსირებული და არა latest-ზე, pull რაიმე ახალს მხოლოდ მაშინ იღებს, როცა ფაილი შეცვალე - რაც სწორედ მიზანია. deploy მაშინ ერთი ხაზის რედაქტირებაა, commit და up -d. უკან დაბრუნება იგივე რედაქტირებაა საპირისპირო მიმართულებით და ის მუშაობს, რადგან ძველი image ჯერ არ წაგიშლია; docker image ls აჩვენებს, რომ ის იქ დგას. შეინახე სულ მცირე წინა tag, სანამ ახალი ერთ დღეს არ გაუძლებს.

ორი რამ, რასაც ეს მარტივი პროცესი არ გაძლევს. არის რამდენიმე წამის ხვრელი, სანამ ძველი კონტეინერი ჩერდება და ახალი იწყება, რომლის დროსაც proxy-ის უკან არაფერი დგას და ვიზიტორები 502-ს იღებენ. ჰობი stack-ისთვის ეს მისაღებია; თუ არა, zero-downtime deploy-ები პატარა სერვერზე ფარავს შაბლონებს, რომლებიც ხვრელს ხურავს. და ბაზა აპლიკაციასთან ერთად ვერსიებად არ იყოფა, ამიტომ გამოშვებას, რომელსაც სქემის ცვლილება სჭირდება, migration ცალკე ნაბიჯად უნდა გაუშვა, სასურველია ისეთად, რომელიც ძველი და ახალი კოდისთვის ორივესთვის უსაფრთხოა.

რომ stack reboot-ის შემდეგ დაბრუნდეს, ყველა სერვისზე restart: unless-stopped ჩვეულებრივ საკმარისია, რადგან Docker daemon ჩატვირთვისას იწყება და მათ თან მოიყოლებს. თუ გინდა, რომ stack მანქანის საკუთარ start-ის თანმიმდევრობას დაუკავშირო, ან გინდა, რომ მან მიერთებულ ფაილურ სისტემას დაელოდოს, ამის ნაცვლად docker compose up -d პატარა systemd unit-ში შეაკავშირე - systemd სერვისები შენი აპლიკაციებისთვის ფაილს შეიცავს.

როცა stack არ ადგება#

`service "app" depends on undefined service db`. ბეჭდვის შეცდომა ან ინდენტაციის შეცდომა. YAML თეთრ სივრცეზეა დამოკიდებული და ორი space კონვენციაა; tab ფაილში სადმე სინტაქსური შეცდომაა. docker compose config ორივეს იჭერს, სანამ რამეს გაუშვებ.

Port is already allocated. სხვა პროცესს ან სხვა Compose project-ს ჰოსტის პორტი უჭირავს. sudo ss -lntp მას დაასახელებს. ორ project-ს ორივეს ერთად პორტ 443-ის გამოქვეყნება არ შეუძლია; სწორედ ამისთვის არის proxy.

აპლიკაცია `db`-ს ვერ წყვეტს. ორივე სერვისი ერთ project-სა და ერთ ქსელში უნდა იყოს. თუ stack-ს ორ compose ფაილზე გაყოფ, ორ ქსელს მიიღებ - ორივეში გამოაცხადე გარე ქსელი, ან დატოვე ერთ ფაილში.

ბაზა ყოველ ჯერზე თავიდან იწყება. volume იქ არ არის მიმაგრებული, სადაც image ელოდება, ამიტომ მონაცემები კონტეინერის ჩასაწერ ფენაში მიდის და მასთან ერთად კვდება. docker compose exec db ls -la /var/lib/postgresql/data ფაილებს უნდა აჩვენებდეს, ხოლო docker volume ls - volume-ს project-ის პრეფიქსით.

`POSTGRES_PASSWORD`-ის შეცვლას ეფექტი არ ჰქონია. ოფიციალური ბაზის image-ები ამ ცვლადებს მხოლოდ ცარიელი მონაცემთა დირექტორიის ინიციალიზაციისას იყენებენ. არსებულ volume-ზე პაროლი ისაა, რაც პირველ დღეს იყო, და მას ბაზის შიგნით ALTER USER-ით ცვლი.

ყველაფერი ჯანსაღია და საიტი 502-ს აბრუნებს. proxy არასწორ პორტს ან არასწორ სახელს აღწევს. შეამოწმე, რომ აპლიკაცია კონტეინერის შიგნით ნამდვილად 0.0.0.0-ზე უსმენს და არა 127.0.0.1-ზე, რადგან კონტეინერის loopback proxy-ის loopback-თან საერთო არ არის.

დისკი ამოიწურა. ძველი image-ები და build ქეში. docker system df აჩვენებს, სად წავიდა; docker image prune -a და docker builder prune მას უსაფრთხოდ ათავისუფლებს. --volumes flag-ს ერიდე, თუ სრულად დარწმუნებული არ ხარ.

ასეთი stack პატარა VDS-ზე კომფორტულად ეტევა: proxy-ს თითქმის არაფერი სჭირდება, PostgreSQL პატარა საიტისთვის გიგაბაიტში კარგად გრძნობს თავს, თუ მას მოარგებ, ხოლო აპლიკაცია ისაა, რაც არის. PostgreSQL-ის მორგება პატარა სერვერებისთვის ამის პარამეტრების მხარეა. რასაც VDS იძლევა და მართვადი გეგმა ვერა, სწორედ ესაა: kernel, Docker daemon და root, ასე რომ stack, რომელიც შენს ფაილშია, ისაა, რაც მუშაობს.

FAQ#

Compose ზედმეტია ერთი კონტეინერისთვის?

ოდნავ, მაგრამ მაინც ამართლებს. ერთსერვისიანი ფაილი იმ flag-ებს ინახავს, რომლებსაც სხვაგვარად ხელახლა აკრეფდი, განახლებას ორ ბრძანებად აქცევს და გაშვებისას არაფერი უჯდება. როცა ბაზას დაამატებ, ის აშკარა გზა ხდება.

გამოვიყენო build: თუ მზა image?

თუ შეგიძლია, build სხვაგან გააკეთე და tag-ირებული image ჩამოტვირთე. სერვერზე build deploy-ებს მანქანის CPU-სა და დისკს აკავშირებს, build ქეშს ავსებს და ნიშნავს, რომ წარუმატებელი build არაფერს გაშვებულს არ გტოვებს. ადგილზე build პატარა პროექტისთვის მისაღებია, თუ წინა image-ს შეინახავ.

docker compose down წაშლის ჩემს ბაზას?

თავისთავად არა. ის კონტეინერებსა და ქსელებს შლის და named volume-ებს ინახავს. docker compose down -v volume-ებს შლის და ეს ბაზას მართლა ანადგურებს, დადასტურების გარეშე.

როგორ გავუშვა რამდენიმე stack ერთ სერვერზე?

თითო დირექტორია, თითო compose.yaml და მხოლოდ ერთი მათგანი აქვეყნებს 80-სა და 443-ს. საერთო proxy ცალკე project-ში გაიტანე გარე ქსელზე, რომელსაც დანარჩენები შეუერთდებიან, ან თითოეულ აპლიკაციას მიეცი განსხვავებული შიდა პორტი და ერთადერთ proxy-ში hostname-ით მარშრუტიზება გააკეთე.

შეიძლება Compose-ის გამოყენება მართვად ჰოსტინგ გეგმაზე?

არა. Compose Docker daemon-ს მართავს, ხოლო მართვადი თამაშის ან აპლიკაციის გეგმა თავად კონტეინერია მის გარეშე. ეს VDS-ზე გადასვლის ერთ-ერთი ყველაზე ნათელი მიზეზია, სადაც daemon და root ანგარიში შენია.

რა ცვლის Compose-ს, როცა ეს stack გაიზრდება?

ხშირად დიდი ხნის განმავლობაში არაფერი. ერთი სერვერი რამდენიმე სერვისით ზუსტად ის ზომაა, რასაც Compose ერგება. როცა ნამდვილად გჭირდება ერთზე მეტი მანქანა, შემდეგი ნაბიჯი scheduler-ია, მას შემდეგ კი გუნდი, რომელიც მას ემსახურება - ორივე დიდი ხარჯია, რომლის ადრე აღებაც ადვილია.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000