From fa79939290940426f890c974830d5fe244bffe94 Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Wed, 8 Jul 2026 12:07:19 -0300 Subject: [PATCH 1/3] chore: manage docker bloat on deployments automatically prune old images and raise warnings for dangling volumes and exited containers on GitHub Actions workflow deployments. Closes #1918 Signed-off-by: Luiz Georg --- .github/workflows/deploy-production.yaml | 6 ++++-- .github/workflows/deploy-staging.yaml | 7 ++++--- .github/workflows/staging-db.yaml | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index c71a34b38..47d471345 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -106,8 +106,10 @@ jobs: cp ~/.env-production dashboard-production/.env && cd dashboard-production && git checkout ${GITHUB_SHA} && - docker compose -f docker-compose-next.yml pull && - docker compose -f docker-compose-next.yml up -d + docker compose up --pull=always --remove-orphans --detach && + docker image prune -fa --filter "until=48h" && + docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" && + docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" " env: SSH_USER: ${{ secrets.STAGING_USER }} diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 26973dc57..63bd85ea4 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -67,9 +67,10 @@ jobs: cp ~/.env-staging dashboard-staging/.env && cd dashboard-staging && git checkout ${GITHUB_SHA} && - docker compose down && - docker compose build --no-cache && - docker compose up -d + docker compose up --build --pull=always --remove-orphans --detach && + docker image prune -fa --filter "until=48h" && + docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" && + docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" " env: SSH_USER: ${{ secrets.STAGING_USER }} diff --git a/.github/workflows/staging-db.yaml b/.github/workflows/staging-db.yaml index 761e8fffa..95099ac90 100644 --- a/.github/workflows/staging-db.yaml +++ b/.github/workflows/staging-db.yaml @@ -24,5 +24,7 @@ jobs: git fetch git checkout ${{ github.event.inputs.GIT_BRANCH }} cd .. - docker compose -f docker-compose-all.yaml --profile=self-hosted build - docker compose -f docker-compose-all.yaml --profile=self-hosted up -d --remove-orphans + docker compose -f docker-compose-all.yaml --profile=self-hosted up --build --pull=always --remove-orphans --detach + docker image prune -fa --filter "until=48h" + docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" + docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" From d8bf89bfc36ec156b648f54c3b9a7191aa79e0ba Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Sat, 18 Jul 2026 16:31:39 -0300 Subject: [PATCH 2/3] fixup! chore: manage docker bloat on deployments Signed-off-by: Luiz Georg --- .github/workflows/deploy-production.yaml | 30 +++++++++++++++++---- .github/workflows/deploy-staging.yaml | 33 +++++++++++++++++++----- .github/workflows/staging-db.yaml | 20 ++++++++++++-- 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 47d471345..7ee2a3c49 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -88,7 +88,8 @@ jobs: needs: start-notification runs-on: ubuntu-latest steps: - - name: Configure host authenticity + - &ssh-host-auth + name: Configure host authenticity run: | mkdir -p ~/.ssh/ && chmod 700 ~/.ssh/ touch ~/.ssh/known_hosts && chmod 600 ~/.ssh/known_hosts @@ -106,10 +107,8 @@ jobs: cp ~/.env-production dashboard-production/.env && cd dashboard-production && git checkout ${GITHUB_SHA} && - docker compose up --pull=always --remove-orphans --detach && - docker image prune -fa --filter "until=48h" && - docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" && - docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" + docker compose -f docker-compose-next.yml pull --policy=always && + docker compose -f docker-compose-next.yml up -d --remove-orphans " env: SSH_USER: ${{ secrets.STAGING_USER }} @@ -131,3 +130,24 @@ jobs: uses: Ilshidur/action-discord@master with: args: "Production Dashboard deployment failed with tag `${{ github.event.inputs.tag }}`" + + cleanup: + needs: deploy-production + runs-on: ubuntu-latest + steps: + - *ssh-host-auth + - name: Prune docker artifacts on remote + env: + SSH_USER: ${{ secrets.STAGING_USER }} + SSH_HOST: ${{ secrets.STAGING_HOST }} + SSH_KEY: ${{ secrets.STAGING_KEY }} + run: | + eval $(ssh-agent -s) + echo "$SSH_KEY" | ssh-add - >/dev/null + ssh "${SSH_USER}@${SSH_HOST}" <<<'EOF' + set -eu + docker image prune -fa --filter "until=48h" + docker builder prune -f --filter "until=48h" + docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" + docker container ls --filter status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" + EOF diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 63bd85ea4..6d577427b 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -49,14 +49,15 @@ jobs: needs: check-migrations runs-on: ubuntu-latest steps: - - name: Configure staging host authenticity + - &ssh-host-auth + name: Configure staging host authenticity run: | mkdir -p ~/.ssh/ && chmod 700 ~/.ssh/ touch ~/.ssh/known_hosts && chmod 600 ~/.ssh/known_hosts echo "$SSH_HOSTKEY" > ~/.ssh/known_hosts env: SSH_HOSTKEY: ${{ secrets.STAGING_HOSTKEY }} - + - name: Deploy to staging run: | eval $(ssh-agent -s) @@ -67,16 +68,36 @@ jobs: cp ~/.env-staging dashboard-staging/.env && cd dashboard-staging && git checkout ${GITHUB_SHA} && - docker compose up --build --pull=always --remove-orphans --detach && - docker image prune -fa --filter "until=48h" && - docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" && - docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" + docker compose pull --ignore-buildable --policy=always && + docker compose build --no-cache && + docker compose up -d --remove-orphans " env: SSH_USER: ${{ secrets.STAGING_USER }} SSH_HOST: ${{ secrets.STAGING_HOST }} SSH_KEY: ${{ secrets.STAGING_KEY }} + cleanup: + needs: deploy-staging + runs-on: ubuntu-latest + steps: + - *ssh-host-auth + - name: Prune docker artifacts on remote + env: + SSH_USER: ${{ secrets.STAGING_USER }} + SSH_HOST: ${{ secrets.STAGING_HOST }} + SSH_KEY: ${{ secrets.STAGING_KEY }} + run: | + eval $(ssh-agent -s) + echo "$SSH_KEY" | ssh-add - >/dev/null + ssh "${SSH_USER}@${SSH_HOST}" <<<'EOF' + set -eu + docker image prune -fa --filter "until=48h" + docker builder prune -f --filter "until=48h" + docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" + docker container ls --filter status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" + EOF + e2e-tests: runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/.github/workflows/staging-db.yaml b/.github/workflows/staging-db.yaml index 95099ac90..007c9c276 100644 --- a/.github/workflows/staging-db.yaml +++ b/.github/workflows/staging-db.yaml @@ -24,7 +24,23 @@ jobs: git fetch git checkout ${{ github.event.inputs.GIT_BRANCH }} cd .. - docker compose -f docker-compose-all.yaml --profile=self-hosted up --build --pull=always --remove-orphans --detach + docker compose -f docker-compose-all.yaml --profile=self-hosted pull --ignore-buildable + docker compose -f docker-compose-all.yaml --profile=self-hosted build + docker compose -f docker-compose-all.yaml --profile=self-hosted up -d --remove-orphans + + cleanup: + runs-on: ubuntu-latest + needs: deploy + steps: + - name: Prune docker artifacts on remote + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.DB_SSH_HOST }} + username: ${{ secrets.DB_SSH_USER }} + key: ${{ secrets.DB_SSH_KEY }} + script: | + set -eu docker image prune -fa --filter "until=48h" + docker builder prune -f --filter "until=48h" docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" - docker container ls -f status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" + docker container ls --filter status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" From 816784b1865a8078346aead76ca06c87a1fb9f60 Mon Sep 17 00:00:00 2001 From: Luiz Georg Date: Wed, 22 Jul 2026 15:48:34 -0300 Subject: [PATCH 3/3] fixup! chore: manage docker bloat on deployments Signed-off-by: Luiz Georg --- .github/workflows/deploy-production.yaml | 2 +- .github/workflows/deploy-staging.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 7ee2a3c49..eeff7142d 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -144,7 +144,7 @@ jobs: run: | eval $(ssh-agent -s) echo "$SSH_KEY" | ssh-add - >/dev/null - ssh "${SSH_USER}@${SSH_HOST}" <<<'EOF' + ssh "${SSH_USER}@${SSH_HOST}" <<'EOF' set -eu docker image prune -fa --filter "until=48h" docker builder prune -f --filter "until=48h" diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 6d577427b..e51b67a35 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -90,7 +90,7 @@ jobs: run: | eval $(ssh-agent -s) echo "$SSH_KEY" | ssh-add - >/dev/null - ssh "${SSH_USER}@${SSH_HOST}" <<<'EOF' + ssh "${SSH_USER}@${SSH_HOST}" <<'EOF' set -eu docker image prune -fa --filter "until=48h" docker builder prune -f --filter "until=48h"