mirror of
https://gitlab.sectorq.eu/home/docker-compose.git
synced 2025-12-14 10:24:53 +01:00
92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
import docker
|
|
import requests
|
|
import os
|
|
import time
|
|
PORTAINER_URL = "https://port.sectorq.eu/api"
|
|
API_KEY = "ptr_/5RkMCT/j3BTaL32vMSDtXFi76yOXRKVFOrUtzMsl5Y="
|
|
HEADERS = {"X-API-Key": f"{API_KEY}"}
|
|
ENDPOINT_ID = 4
|
|
client = docker.from_env()
|
|
|
|
# Keep track of which stacks we already stopped
|
|
stopped_stacks = {}
|
|
|
|
def get_stack_by_name(stack_name):
|
|
url = f"{PORTAINER_URL}/stacks"
|
|
r = requests.get(url, headers=HEADERS)
|
|
r.raise_for_status()
|
|
for s in r.json():
|
|
if s['Name'] == stack_name:
|
|
return s
|
|
return None
|
|
|
|
def stop_stack(stack_name):
|
|
if stack_name in stopped_stacks:
|
|
return
|
|
stack = get_stack_by_name(stack_name)
|
|
if not stack:
|
|
print(f"[INFO] Stack {stack_name} not found, skipping stop")
|
|
return
|
|
url = f"{PORTAINER_URL}/stacks/{stack['Id']}/stop?endpointId={ENDPOINT_ID}"
|
|
print(f"url: {url}")
|
|
r = requests.post(url, headers=HEADERS)
|
|
if r.status_code == 200:
|
|
print(f"[OK] Stack {stack_name} stopped")
|
|
else:
|
|
print(f"[ERROR] Failed to stop stack {stack_name}: {r.text}")
|
|
stopped_stacks[stack_name] = True
|
|
|
|
def start_stack(stack_name):
|
|
stack = get_stack_by_name(stack_name)
|
|
if not stack:
|
|
print(f"[INFO] Stack {stack_name} not found, skipping start")
|
|
return
|
|
url = f"{PORTAINER_URL}/stacks/{stack['Id']}/start?endpointId={ENDPOINT_ID}"
|
|
r = requests.post(url, headers=HEADERS)
|
|
if r.status_code == 200:
|
|
print(f"[OK] Stack {stack_name} started")
|
|
else:
|
|
print(f"[ERROR] Failed to start stack {stack_name}: {r.text}")
|
|
|
|
def backup_volume(vol):
|
|
vol_name = vol.name
|
|
backup_file = f"/backup/{vol_name}.tar"
|
|
print(f"[INFO] Backing up volume {vol_name} → {backup_file}")
|
|
# Use a temporary container to archive the volume
|
|
client.containers.run(
|
|
image="alpine",
|
|
command=f"tar czf /backup/{vol_name}.tar -C /data .",
|
|
volumes={vol_name: {'bind': '/data', 'mode': 'ro'},
|
|
"/backup": {'bind': '/backup', 'mode': 'rw'}},
|
|
remove=True
|
|
)
|
|
|
|
def main():
|
|
volumes = client.volumes.list()
|
|
stack_volumes = {}
|
|
normal_volumes = []
|
|
|
|
# Categorize volumes by stack
|
|
for vol in volumes:
|
|
labels = vol.attrs.get('Labels', {})
|
|
stack_name = labels.get('com.docker.stack.namespace')
|
|
if stack_name:
|
|
stack_volumes.setdefault(stack_name, []).append(vol)
|
|
else:
|
|
normal_volumes.append(vol)
|
|
|
|
# Backup stacks
|
|
for stack_name, vols in stack_volumes.items():
|
|
stop_stack(stack_name)
|
|
#input("Press Enter to continue with backup...")
|
|
for v in vols:
|
|
backup_volume(v)
|
|
time.sleep(10) # Small delay to ensure stack is fully stopped
|
|
start_stack(stack_name)
|
|
|
|
# Backup normal volumes
|
|
for v in normal_volumes:
|
|
backup_volume(v)
|
|
|
|
if __name__ == "__main__":
|
|
main() |