Skip to content

Commit

Permalink
Document socket-proxy permissions, return early when update failed on…
Browse files Browse the repository at this point in the history
… scaling down (#343)

* Do not await containers when there was an error on scaling

* Add test case for usage with socket proxy

* Add documentation on required permissions for docker-socket-proxy

* Add full list of used Docker APIs to doc

* CONTAINER_START and CONTAINER_STOP is not needed
  • Loading branch information
m90 authored Feb 5, 2024
1 parent 6029225 commit 0f224e4
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 3 deletions.
4 changes: 2 additions & 2 deletions cmd/backup/stop_restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,9 @@ func (s *script) stopContainersAndServices() (func() error, error) {
warnings, err := scaleService(s.cli, svc.serviceID, 0)
if err != nil {
scaleDownErrors.append(err)
} else {
scaledDownServices = append(scaledDownServices, svc)
return
}
scaledDownServices = append(scaledDownServices, svc)
for _, warning := range warnings {
s.logger.Warn(
fmt.Sprintf("The Docker API returned a warning when scaling down service %s: %s", svc.serviceID, warning),
Expand Down
30 changes: 29 additions & 1 deletion docs/how-tos/use-custom-docker-host.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,33 @@ If you are interfacing with Docker via TCP, set `DOCKER_HOST` to the correct URL
DOCKER_HOST=tcp://docker_socket_proxy:2375
```

In case you are using a socket proxy, it must support `GET` and `POST` requests to the `/containers` endpoint. If you are using Docker Swarm, it must also support the `/services` endpoint. If you are using pre/post backup commands, it must also support the `/exec` endpoint.
If you do this as you seek to restrict access to the Docker socket, this tool is potentially calling the following Docker APIs:

| API | When |
|-|-|
| `Info` | always |
| `ContainerExecCreate` | running commands from `exec-labels` |
| `ContainerExecAttach` | running commands from `exec-labels` |
| `ContainerExecInspect` | running commands from `exec-labels` |
| `ContainerList` | always |
`ServiceList` | Docker engine is running in Swarm mode |
| `ServiceInspect` | Docker engine is running in Swarm mode |
| `ServiceUpdate` | Docker engine is running in Swarm mode and `stop-during-backup` is used |
| `ConatinerStop` | `stop-during-backup` labels are applied to containers |
| `ContainerStart` | `stop-during-backup` labels are applied to container |

---

In case you are using [`docker-socket-proxy`][proxy], this means following permissions are required:

| Permission | When |
|-|-|
| INFO | always required |
| CONTAINERS | always required |
| POST | required when using `stop-during-backup` or `exec` labels |
| EXEC | required when using `exec`-labeled commands |
| SERVICES | required when Docker Engine is running in Swarm mode |
| NODES | required when labeling services `stop-during-backup` |
| TASKS | required when labeling services `stop-during-backup` |

[proxy]: https://github.com/Tecnativa/docker-socket-proxy
40 changes: 40 additions & 0 deletions test/proxy/docker-compose.swarm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2020-2021 - Offen Authors <[email protected]>
# SPDX-License-Identifier: Unlicense

version: '3.8'

services:
backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary}
environment:
BACKUP_FILENAME: test.tar.gz
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
DOCKER_HOST: tcp://docker_socket_proxy:2375
volumes:
- pg_data:/backup/pg_data:ro
- ${LOCAL_DIR:-local}:/archive

docker_socket_proxy:
image: tecnativa/docker-socket-proxy:0.1
environment:
INFO: ${ALLOW_INFO:-1}
CONTAINERS: ${ALLOW_CONTAINERS:-1}
SERVICES: ${ALLOW_SERVICES:-1}
POST: ${ALLOW_POST:-1}
TASKS: ${ALLOW_TASKS:-1}
NODES: ${ALLOW_NODES:-1}
volumes:
- /var/run/docker.sock:/var/run/docker.sock

pg:
image: postgres:14-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- pg_data:/var/lib/postgresql/data
deploy:
labels:
- docker-volume-backup.stop-during-backup=true

volumes:
pg_data:
36 changes: 36 additions & 0 deletions test/proxy/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2020-2021 - Offen Authors <[email protected]>
# SPDX-License-Identifier: Unlicense

version: '3.8'

services:
backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary}
environment:
BACKUP_FILENAME: test.tar.gz
BACKUP_CRON_EXPRESSION: 0 0 5 31 2 ?
DOCKER_HOST: tcp://docker_socket_proxy:2375
volumes:
- pg_data:/backup/pg_data:ro
- ${LOCAL_DIR:-local}:/archive

docker_socket_proxy:
image: tecnativa/docker-socket-proxy:0.1
environment:
INFO: ${ALLOW_INFO:-1}
CONTAINERS: ${ALLOW_CONTAINERS:-1}
POST: ${ALLOW_POST:-1}
volumes:
- /var/run/docker.sock:/var/run/docker.sock

pg:
image: postgres:14-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- pg_data:/var/lib/postgresql/data
labels:
- docker-volume-backup.stop-during-backup=true

volumes:
pg_data:
76 changes: 76 additions & 0 deletions test/proxy/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/sh

set -e

cd $(dirname $0)
. ../util.sh
current_test=$(basename $(pwd))

export LOCAL_DIR=$(mktemp -d)

docker compose up -d --quiet-pull
sleep 5

# The default configuration in docker-compose.yml should
# successfully create a backup.
docker compose exec backup backup

sleep 5

expect_running_containers "3"

if [ ! -f "$LOCAL_DIR/test.tar.gz" ]; then
fail "Archive was not created"
fi
pass "Found relevant archive file."

# Disabling POST should make the backup run fail
ALLOW_POST="0" docker compose up -d
sleep 5

set +e
docker compose exec backup backup
if [ $? = "0" ]; then
fail "Expected invocation to exit non-zero."
fi
set -e
pass "Invocation exited non-zero."

docker compose down --volumes

# Next, the test is run against a Swarm setup

docker swarm init

export LOCAL_DIR=$(mktemp -d)

docker stack deploy --compose-file=docker-compose.swarm.yml test_stack

sleep 20

# The default configuration in docker-compose.swarm.yml should
# successfully create a backup in Swarm mode.
docker exec $(docker ps -q -f name=backup) backup

if [ ! -f "$LOCAL_DIR/test.tar.gz" ]; then
fail "Archive was not created"
fi

pass "Found relevant archive file."

sleep 5
expect_running_containers "3"

# Disabling POST should make the backup run fail
ALLOW_POST="0" docker stack deploy --compose-file=docker-compose.swarm.yml test_stack

sleep 20

set +e
docker exec $(docker ps -q -f name=backup) backup
if [ $? = "0" ]; then
fail "Expected invocation to exit non-zero."
fi
set -e

pass "Invocation exited non-zero."

0 comments on commit 0f224e4

Please sign in to comment.