Cách khởi động lại một container với docker-compose


332

Tôi có một docker-compose.ymltập tin chứa 4 container: redis, postgres, api, worker

Trong quá trình phát triển worker, tôi thường cần khởi động lại nó để áp dụng các thay đổi. Có cách nào tốt để khởi động lại một container (ví dụ worker) mà không cần khởi động lại các container khác không?


2
Công cụ khởi động lại docker-compose -f docker-compose.yml
Jinna Balu

Câu trả lời:


395

Nó rất đơn giản: Sử dụng lệnh:

docker-compose restart worker

Bạn có thể đặt thời gian chờ dừng trước khi giết container (tính bằng giây)

docker-compose restart -t 30 worker

Lưu ý rằng điều này sẽ khởi động lại container nhưng không xây dựng lại. Nếu bạn muốn áp dụng các thay đổi của mình và sau đó khởi động lại, hãy xem các câu trả lời khác.


3
đối với tôi nó đã hoạt động, nhưng một câu hỏi chung nếu được phép ở đây: 'khởi động lại' có quan tâm đến các container được liên kết và cập nhật / etc / hosts hay không 'khởi động lại' thay đổi bất kỳ IP nào?
michabbb

Các container được liên kết theo tên và thường là IP duy nhất bạn cần lo lắng là IP máy chủ docker bên ngoài (thường là 192.168.99.100). Trường hợp có thể có một số rắc rối là nếu bạn, nói, khởi động lại một bộ chứa cơ sở dữ liệu mà các bộ chứa khác được kết nối. Các thùng chứa phụ thuộc sẽ phải đủ khả năng phục hồi để kết nối lại.
Ryan Kimber

20
OP tuyên bố rằng anh ta cần "khởi động lại nó để áp dụng các thay đổi". Theo các tài liệu, các docker-compose restartlệnh sẽ KHÔNG áp dụng bất kỳ thay đổi nào. "Nếu bạn thay đổi docker-compose.ymlcấu hình của mình, những thay đổi này sẽ không được phản ánh sau khi chạy lệnh này." Do đó sử dụng docker-compose up -d --build. docs.docker.com/compose/reference/restart
Featherbelly

5
nb, worker là tên được đặt cho dịch vụ trong tệp yaml và không phải bất cứ thứ gì bạn thấy khi chạydocker ps -a
worc

2
Câu trả lời khác này tốt hơn nhiều so với stackoverflow.com/a/39501539/292408 , vì restartkhông áp dụng các thay đổi ngay cả khi bạn đã chạy một docker-compose build <container name>và đây là một câu trả lời không hoạt động / không chính xác.
Elijah Lynn

170

Các câu trả lời khác để khởi động lại một nút là trên mục tiêu , docker-compose restart worker. Điều đó sẽ trả lại container đó, nhưng không bao gồm bất kỳ thay đổi nào, ngay cả khi bạn xây dựng lại nó một cách riêng biệt. Bạn có thể tự stop, rm, create, và start, nhưng có một phương pháp dễ dàng hơn nhiều.

Nếu bạn đã cập nhật mã của mình, bạn có thể thực hiện quá trình xây dựng và tải lại trong một bước duy nhất với:

docker-compose up --detach --build

Điều đó trước tiên sẽ xây dựng lại hình ảnh của bạn từ bất kỳ mã thay đổi nào, nhanh chóng nếu không có thay đổi kể từ khi bộ đệm được sử dụng lại. Và sau đó nó chỉ thay thế các container đã thay đổi. Nếu hình ảnh đã tải xuống của bạn cũ, bạn có thể đặt trước lệnh trên với:

docker-compose pull

Để tải xuống bất kỳ hình ảnh thay đổi nào trước tiên (các thùng chứa sẽ không được khởi động lại cho đến khi bạn chạy một lệnh như uptrên). Làm một điểm dừng ban đầu là không cần thiết.

Và để chỉ làm điều này cho một dịch vụ duy nhất, hãy làm theo lệnh lên hoặc kéo với các dịch vụ bạn muốn chỉ định, ví dụ:

docker-compose up --detach --build worker

Đây là một ví dụ nhanh về tùy chọn đầu tiên, Dockerfile được cấu trúc để giữ cho các phần thường xuyên thay đổi của mã gần cuối. Trong thực tế, các yêu cầu được kéo riêng rẽ pip installvì tệp đó hiếm khi thay đổi. Và vì các thùng chứa nginx và redis đã được cập nhật, chúng không được khởi động lại. Tổng thời gian cho toàn bộ quá trình dưới 6 giây:

$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
 ---> fc479af56697
Step 2 : WORKDIR /app
 ---> Using cache
 ---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
 ---> Using cache
 ---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> 85b878795479
Step 5 : ADD . /app
 ---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
 ---> Running in a5b3d3f80cd4
 ---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
 ---> Running in 0d69957bda4c
 ---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1

real    0m5.959s
user    0m0.508s
sys     0m0.076s

Điều này thật thú vị, nhưng nó có thể được sử dụng cùng với -no-cachetùy chọn không? Nói rằng tôi thêm một cái gì đó vào tôi package.jsoncần và để lại RUN npm installnhưng Dockerfilebản thân vẫn không thay đổi
Augustin Riedinger

2
@augustinriedinger Nếu tập tin đầu vào của bạn được thay đổi và bạn bao gồm rằng với một COPYlệnh, mà sẽ phá vỡ bộ nhớ cache tự động.
BMitch

1
@augustinriedinger nhờ. Tôi điện thoại di động vì vậy tôi không thể nhìn thấy các câu hỏi liên quan. Từ các bước trong câu hỏi của bạn, bạn đã có một COPYlệnh trong Dockerfile của bạn. Các git pullsẽ cập nhật các tập tin package.json và xây dựng bộ nhớ cache sẽ phá vỡ khi Docker thấy bạn sao chép trong một tập tin khác nhau.
BMitch

1
Cảm ơn không biết về chức năng này! Tôi đã sử dụng ADDthay vì COPYnhưng rõ ràng sau này là một cách thực hành tốt nhất vì vậy tôi sẽ thực hiện nó!
Augustin Riedinger

1
@augustinriedinger ADDsẽ có kết quả tương tự như COPYtrên bức tượng bán thân cache, nhưng (như đề xuất trong thực tiễn tốt nhất liên kết) hầu hết đều không cần khả năng thêm vì vậy tôi thậm chí không chú ý nhiều đến nó.
BMitch

28

Để khởi động lại một dịch vụ với các thay đổi ở đây là các bước tôi đã thực hiện:

docker-compose stop -t 1 worker
docker-compose build worker
docker-compose create worker
docker-compose start worker

10
Nếu bạn cần thay đổi để áp dụng với một xây dựng, bạn có thể dễ dàng làm một docker-compose up -d --buildvà nó sẽ xây dựng lại tất cả mọi thứ và khởi động lại bất kỳ container đã thay đổi. Không cần dừng lại trước, với thời gian chết, và các lệnh tạo và bắt đầu riêng biệt.
BMitch

4
Có, nếu bạn muốn khởi động lại tất cả các dịch vụ, nhưng OP chỉ muốn khởi động lại một dịch vụ duy nhất và không khởi động lại các dịch vụ khác
Jeff

3
Xem câu trả lời tôi đã đăng, trong ví dụ, ý upchí chỉ tạo lại container đã được thay đổi và do đó cần khởi động lại.
BMitch

18

Theo lệnh

docker-compose restart worker

sẽ chỉ DỪNG và BẮT ĐẦU container. tức là không tải bất kỳ thay đổi nào từ docker-compose.xml

STOP tương tự như ngủ đông trong PC. Do đó, dừng / bắt đầu sẽ không tìm kiếm bất kỳ thay đổi nào được thực hiện trong tệp cấu hình. Để tải lại từ công thức của bộ chứa (docker-compose.xml), chúng ta cần xóa và tạo bộ chứa (Tương tự như khởi động lại PC)

Vì vậy, các lệnh sẽ như sau

docker-compose stop worker       // go to hibernate
docker-compose rm worker        // shutdown the PC 
docker-compose create worker     // create the container from image and put it in hibernate

docker-compose start worker //bring container to life from hibernation

+1, cảm ơn rất nhiều! Đối với rmtùy chọn dòng -ftrở nên tiện dụng (không có dấu nhắc) và với docker hiện tại createstartđược hợp nhất thành up(vì vậy trong tổng số chúng ta có 3 lệnh không phải 4) và cho uptùy chọn -dlà hữu ích (thực thi trong nền).
Astrowalker

10

Khởi động lại dịch vụ với tập tin docker-compose

docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]

Ca sử dụng số 1: Nếu COMPOSE_FILE_NAME là docker-compose.ymlvà dịch vụ là công nhân

docker-compose restart worker

Ca sử dụng số 2: Nếu tên tệp là sample.ymlvà dịch vụ là worker

docker-compose -f sample.yml restart worker

Theo mặc định, docker-compose tìm kiếm docker-compose.ymlnếu chúng ta chạy docker-composelệnh, nếu không chúng ta có cờ để đặt tên tệp cụ thể với-f [FILE_NAME].yml


7

Đơn giản 'Docker' lệnh không biết gì về 'công nhân' container. Sử dụng lệnh như thế này

docker-compose -f docker-compose.yml restart worker


4
không hoạt động - những thay đổi mới đối với coker-compose.yml không được áp dụng khi khởi động lại
jlee

3

Khởi động lại container

Nếu bạn muốn khởi động lại container của mình:

docker-compose restart servicename

Hãy nghĩ về lệnh này là "chỉ cần khởi động lại container theo tên của nó", tương đương với docker restartlệnh.

Lưu ý:

  1. Nếu bạn thay đổi các biến ENV, chúng sẽ không được cập nhật trong vùng chứa. Bạn cần phải dừng nó và bắt đầu lại. Hoặc, sử dụng lệnh đơn docker-compose upsẽ phát hiện các thay đổi và tạo lại container.

  2. Như nhiều người khác đã đề cập, nếu bạn tự thay đổi docker-compose.ymltệp, khởi động lại đơn giản sẽ không áp dụng những thay đổi đó.

  3. Nếu bạn sao chép mã của mình bên trong vùng chứa ở giai đoạn xây dựng ( Dockerfilebằng cách sử dụng ADDhoặc COPYlệnh), mỗi khi mã thay đổi, bạn phải xây dựng lại vùng chứa ( docker-compose build).

Tương quan với mã của bạn

docker-compose restartsẽ hoạt động hoàn toàn tốt, nếu mã của bạn được ánh xạ đường dẫn vào vùng chứa theo chỉ thị âm lượng docker-compose.ymlnhư vậy:

services:

  servicename:
    volumes:
      - .:/code

Nhưng tôi khuyên bạn nên sử dụng tải lại mã trực tiếp, có thể được cung cấp bởi khung lựa chọn của bạn trong chế độ DEBUG (cách khác, bạn có thể tìm kiếm các gói tự động tải lại bằng ngôn ngữ bạn chọn). Thêm điều này sẽ loại bỏ sự cần thiết phải khởi động lại container mỗi lần sau khi mã của bạn thay đổi, thay vào đó tải lại quá trình bên trong.


1

Câu trả lời ở đây đang nói về sự phản ánh của sự thay đổi trên tệp docker-compose.yml.

Nhưng điều gì sẽ xảy ra nếu tôi muốn kết hợp các thay đổi tôi đã thực hiện trong mã của mình và tôi tin rằng điều đó sẽ chỉ có thể bằng cách xây dựng lại hình ảnh và tôi thực hiện theo các lệnh sau

1. dừng container

docker stop container-id

2. loại bỏ container docker

docker rm container-id

3. loại bỏ hình ảnh docker

docker rmi image-id

4. soạn lại container

docker-compose up container-name
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.