如何使用docker-compose重新启动单个容器

时间:2015-07-16 23:55:01

标签: docker docker-compose

我有一个包含4个容器的docker-compose.yml文件:redis,postgres,api,worker

在开发worker期间,我经常需要重新启动它才能应用更改。有没有什么好方法可以重新启动容器(例如worker)而无需重新启动其他容器?

9 个答案:

答案 0 :(得分:292)

非常简单:使用命令:

docker-compose restart -t 30 worker

您可以设置在杀死容器之前等待停止的时间(以秒为单位)

setkey()

请注意,这将重新启动容器,但不会重建容器。如果要应用更改然后重新启动,请查看其他答案。

答案 1 :(得分:121)

重新启动单个节点的其他答案都在目标docker-compose restart worker上。这将弹回该容器,但不包括任何更改,即使您单独重建它。您可以手动stoprmcreatestart,但有更简单的方法。

如果您已更新代码,则可以使用以下步骤执行构建和重新加载:

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文件重启服务

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

这同时为我完成了两个主要目标:

  1. 定位单个worker容器
  2. 重新生成并重新启动它

希望这可以帮助其他人到达这里。

答案 8 :(得分:0)

重新启动容器

如果您只想重启容器:

docker-compose restart servicename

将此命令视为“只是通过其名称重新启动容器”,相当于docker restart命令。

注意警告:

  1. 如果更改了ENV变量,则它们不会在容器中更新。您需要停止它并重新开始。或者,使用单个命令docker-compose up将检测到更改并重新创建容器。

  2. 正如许多其他人提到的那样,如果您更改了docker-compose.yml文件本身,则简单的重启将不会应用这些更改。

  3. 如果在构建阶段(在Dockerfile中使用ADDCOPY命令在容器中复制代码),则每次代码更改时,都必须重新构建容器({docker-compose build)。

与您的代码相关

docker-compose restart应该可以正常工作,如果您的代码通过docker-compose.yml中的volume指令将路径映射到容器中,就像这样:

services:

  servicename:
    volumes:
      - .:/code

但是我建议使用实时代码重载,它可能是由您选择的框架在DEBUG模式下提供的(或者,您可以使用您选择的语言搜索自动重载软件包)。添加此选项后,您无需在代码更改后每次都重新启动容器,而需要在内部重新加载进程。