Script to recreate a stack

I’m trying to come up with a script that recreates containers for cases like mongo where you can provide scripts to be run when container gets created. So far I have this:

#!/usr/bin/env bash
set -eu
name=a1

containers=()
for task_id in $(
    docker stack ps \
        --format '{{.ID}}' \
        "$name"
); do
    read -r container_id image <<< $(docker inspect \
        --format '{{.Status.ContainerStatus.ContainerID}} {{.Spec.ContainerSpec.Image}}' \
        "$task_id")
    containers+=("$container_id")
    printf '%s %s\n' "$container_id" "$image"
done

# stop
if (( ${#containers[@]} )); then
    docker stack rm "$name"
    for c in "${containers[@]}"; do
        printf '%s\n' "$c"
    	docker wait "$c"
    done
fi

sleep 5

# start
set -a
. .env
docker stack deploy -c docker-cloud.yml --prune --with-registry-auth "$name"

What I don’t like is the sleep part. Without it it says:

f6681786269c2da1981dcefce9c413d9c71207e1ad20f79adc58667374519487 mongo:3.2@sha256:9e09fe9e747fb0ee1e64b572818e7397eb9a73e36a2b08bcc7846e9acf0a587f
1b7f7e2e05e08a5a15545dc5402370fc090cad5163c41d83ad16eaee2395ffe9 registry/a1:latest@sha256:10191560c71b2c1e7454da95e35b93bcf0445355e9ecc99745acad9f3438e659
f08da147918feac2e1632a6c6abf382ac7e0c9b0065cad4151567889717528cd nginx:stable@sha256:32fdf92b4e986e109e4db0865758020cb0c3b70d6ba80d02fe87bad5cc3dc228
Removing service a1_app
Removing service a1_mongo
Removing service a1_nginx
Removing network a1_app
f6681786269c2da1981dcefce9c413d9c71207e1ad20f79adc58667374519487
0
1b7f7e2e05e08a5a15545dc5402370fc090cad5163c41d83ad16eaee2395ffe9
1
f08da147918feac2e1632a6c6abf382ac7e0c9b0065cad4151567889717528cd
0
Creating service a1_nginx
failed to create service a1_nginx: Error response from daemon: network a1_app not found

With sleep:

c98831022899afb349176c8097673688156f85d9e2b6d02edab7427d131355cc mongo:3.2@sha256:9e09fe9e747fb0ee1e64b572818e7397eb9a73e36a2b08bcc7846e9acf0a587f
8af304b3e2ef3dcee5a97f5b95bec365fa4657848004c0855d7381711ca1b09d registry/a1:latest@sha256:10191560c71b2c1e7454da95e35b93bcf0445355e9ecc99745acad9f3438e659
afc8b19bedc369885d51acf159e11885cb4a930ed46eef9c337adb725b81410b nginx:stable@sha256:32fdf92b4e986e109e4db0865758020cb0c3b70d6ba80d02fe87bad5cc3dc228
Removing service a1_app
Removing service a1_mongo
Removing service a1_nginx
Removing network a1_app
c98831022899afb349176c8097673688156f85d9e2b6d02edab7427d131355cc
0
8af304b3e2ef3dcee5a97f5b95bec365fa4657848004c0855d7381711ca1b09d
1
afc8b19bedc369885d51acf159e11885cb4a930ed46eef9c337adb725b81410b
0
Creating network a1_app
Creating service a1_nginx
Creating service a1_app
Creating service a1_mongo

So my guess is that by the time docker stack deploy is run, network is not fully removed. So it doesn’t try to create it. And as such creating a1_nginx fails.

Do you see a way to overcome this?

Well, I’ve just realized that docker stack deploy recreates containers :smiley: So any changes in /docker-entrypoint-initdb.d/ take effect.

Actually, I’ve just tried the other thing. Change entrypoint file (with volumes) without rebuilding an image. And it turned out docker stack deploy doesn’t recreate image based on ruby. So, changes didn’t take effect. I’m not sure why it does that for mongo.

UPD I see, with mongo I changed docker-compose.yml, particularly the part about mongo (commented out or uncommented a volume), so it restarted the container. For ruby app I didn’t do that.