我有一个包含4个容器的docker-compose.yml
文件:redis,postgres,api,worker
在开发worker期间,我经常需要重新启动它才能应用更改。有没有什么好方法可以重新启动容器(例如worker
)而无需重新启动其他容器?
答案 0 :(得分:292)
非常简单:使用命令:
docker-compose restart -t 30 worker
您可以设置在杀死容器之前等待停止的时间(以秒为单位)
setkey()
请注意,这将重新启动容器,但不会重建容器。如果要应用更改然后重新启动,请查看其他答案。
答案 1 :(得分:121)
重新启动单个节点的其他答案都在目标docker-compose restart worker
上。这将弹回该容器,但不包括任何更改,即使您单独重建它。您可以手动stop
,rm
,create
和start
,但有更简单的方法。
如果您已更新代码,则可以使用以下步骤执行构建和重新加载:
docker-compose up --detach --build
这将首先从任何已更改的代码重建您的图像,如果自重用缓存后没有任何更改,这将很快。然后它只替换更改的容器。如果下载的图像是陈旧的,则可以在上面的命令之前添加:
docker-compose pull
首先下载任何已更改的图像(在运行上述up
之类的命令之前,不会重新启动容器)。不需要进行初始停止。
要仅针对单个服务执行此操作,请使用您要指定的服务执行up或pull命令,例如:
docker-compose up --detach --build worker
这是第一个选项的快速示例,Dockerfile的结构使代码的频繁变化部分接近结束。事实上,pip install
的需求是单独提取的,因为该文件很少更改。由于nginx和redis容器是最新的,因此它们没有重新启动。整个过程的总时间不到6秒:
$ 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
答案 2 :(得分:18)
要重新启动带有更改的服务,请执行以下步骤:
#include <QLayout>
QT_FORWARD_DECLARE_CLASS(QPropertyAnimation)
class AnimLayout : public QLayout
{
Q_OBJECT
Q_PROPERTY(QPoint delta
READ delta
WRITE setDelta
NOTIFY deltaChanged)
Q_PROPERTY(QRect widgetRect
READ widgetRect
WRITE setWidgetRect
NOTIFY widgetRectChanged)
Q_PROPERTY(bool active
READ isDeltaActive
WRITE setDeltaActive
NOTIFY deltaActiveChanged)
public:
explicit AnimLayout(QWidget *parent = 0);
~AnimLayout();
QPoint delta() const;
void setDelta(const QPoint &value);
QSize sizeHint() const;
void setGeometry(const QRect &);
QSize minimumSize() const;
int count() const;
QSize deltaSize() const;
QRect widgetRect() const;
void setWidgetRect(const QRect &value);
bool isDeltaActive() const;
void setDeltaActive(bool active = true);
void updateItemPosition();
private:
void addItem(QLayoutItem *item);
QLayoutItem *itemAt(int index) const;
QLayoutItem *takeAt(int index);
signals:
void deltaChanged(const QPoint &value);
void widgetRectChanged(const QRect &value);
void deltaActiveChanged(bool active);
public slots:
void testIt();
private:
QLayoutItem *item;
QPropertyAnimation *animation;
QPoint mDelta;
bool mDeltaActive;
};
///////////////////////////////////////////////////////////
#include "animlayout.h"
#include <QPropertyAnimation>
AnimLayout::AnimLayout(QWidget *parent) :
QLayout(parent) ,
item(0)
{
animation = new QPropertyAnimation(this);
animation->setPropertyName("widgetRect");
animation->setDuration(400);
animation->setTargetObject(this);
mDeltaActive = false;
}
AnimLayout::~AnimLayout()
{
delete item;
}
QPoint AnimLayout::delta() const
{
return mDelta;
}
void AnimLayout::setDelta(const QPoint &value)
{
if (mDelta != value) {
mDelta = value;
emit deltaChanged(mDelta);
invalidate();
}
}
void AnimLayout::addItem(QLayoutItem *newItem)
{
Q_ASSERT(!item);
animation->stop();
item =newItem;
emit widgetRectChanged(item->geometry());
invalidate();
}
QSize AnimLayout::sizeHint() const
{
if (!item)
return QSize();
QSize result(item->sizeHint());
result += deltaSize();
int m = 2*margin();
result += QSize(m,m);
return result;
}
void AnimLayout::updateItemPosition()
{
QRect dest = contentsRect();
QPoint d = delta();
if (isDeltaActive()) {
d = -d;
}
if (d.x()!=0) {
if (d.x()>0) {
dest.setLeft(dest.left()+d.x());
} else {
dest.setRight(dest.right()+d.x());
}
}
if (d.y()) {
if (d.y()>0) {
dest.setTop(dest.top()+d.y());
} else {
dest.setBottom(dest.bottom()+d.y());
}
}
animation->setEndValue(dest);
if (widgetRect()!=dest) {
animation->start();
}
}
void AnimLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
updateItemPosition();
}
QLayoutItem *AnimLayout::itemAt(int i) const
{
return i==0?item:0;
}
QLayoutItem *AnimLayout::takeAt(int i)
{
Q_ASSERT(i==0);
QLayoutItem *r = item;
item = 0;
return r;
}
void AnimLayout::testIt()
{
setDeltaActive(!isDeltaActive());
}
QRect AnimLayout::widgetRect() const
{
if (item)
return item->geometry();
return QRect();
}
void AnimLayout::setWidgetRect(const QRect &value)
{
if (item && item->geometry()!=value) {
item->setGeometry(value);
emit widgetRectChanged(item->geometry());
}
}
bool AnimLayout::isDeltaActive() const
{
return mDeltaActive;
}
void AnimLayout::setDeltaActive(bool active)
{
if (active!=mDeltaActive) {
mDeltaActive = active;
animation->stop();
updateItemPosition();
emit deltaActiveChanged(active);
}
}
QSize AnimLayout::minimumSize() const
{
QSize result(deltaSize());
if (item) {
result += item->minimumSize();
}
int m = 2*margin();
result += QSize(m,m);
return result;
}
int AnimLayout::count() const
{
return item?1:0;
}
QSize AnimLayout::deltaSize() const
{
return QSize(qAbs(mDelta.x()), qAbs(mDelta.y()));
}
答案 3 :(得分:8)
以下命令
docker-compose restart worker
只会停止并启动容器。也就是说,无需从docker-compose.xml
加载任何更改STOP类似于在PC中进行休眠。因此,停止/启动将不会在配置文件中查找任何更改。要从容器的配方(docker-compose.xml)重新加载,我们需要删除并创建容器(类似于重启PC的类推)
所以命令如下
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
答案 4 :(得分:5)
简单的'docker'命令对'worker'容器一无所知。 使用这样的命令
docker-compose -f docker-compose.yml restart worker
答案 5 :(得分:5)
这里的答案是关于docker-compose.yml文件中更改的反映。
但是,如果我想将自己所做的更改纳入代码中,该怎么办?我相信只有通过重建图像并使用以下命令才能实现
1。 docker容器停止
docker stop container-id
2。移除Docker容器
docker rm container-id
3。移除docker图像
docker rmi image-id
4。再次组成容器
docker-compose up container-name
答案 6 :(得分:4)
docker-compose -f compose-file.yml restart servieName
docker-compose.yml
并且服务为worker docker-compose restart worker
sample.yml
和服务为worker docker-compose -f sample.yml restart worker
就这样
答案 7 :(得分:2)
由于其他一些答案包括有关重建的信息,并且我的用例也需要重建,因此我有一个更好的解决方案(与之相比)。
仍然有一种方法可以轻松地仅将一个worker
容器作为目标,而这两个容器都可以在同一行中重建+重新启动它,尽管实际上并不是单个命令。对我来说,最好的解决方案是只需重建并重新启动:
docker-compose build worker && docker-compose restart worker
这同时为我完成了两个主要目标:
worker
容器希望这可以帮助其他人到达这里。
答案 8 :(得分:0)
如果您只想重启容器:
docker-compose restart servicename
将此命令视为“只是通过其名称重新启动容器”,相当于docker restart
命令。
如果更改了ENV变量,则它们不会在容器中更新。您需要停止它并重新开始。或者,使用单个命令docker-compose up
将检测到更改并重新创建容器。
正如许多其他人提到的那样,如果您更改了docker-compose.yml
文件本身,则简单的重启将不会应用这些更改。
如果在构建阶段(在Dockerfile
中使用ADD
或COPY
命令在容器中复制代码),则每次代码更改时,都必须重新构建容器({docker-compose build
)。
docker-compose restart
应该可以正常工作,如果您的代码通过docker-compose.yml
中的volume指令将路径映射到容器中,就像这样:
services:
servicename:
volumes:
- .:/code
但是我建议使用实时代码重载,它可能是由您选择的框架在DEBUG模式下提供的(或者,您可以使用您选择的语言搜索自动重载软件包)。添加此选项后,您无需在代码更改后每次都重新启动容器,而需要在内部重新加载进程。