1- name : Build & Push (Compose/Bake)
1+ name : docker-compose-ci
22
33on :
44 push :
5- branches : [ "main", "master" ]
5+ branches : [ master ]
6+ tags : [ 'v*.*.*' ] # v1.2.3 -> release images
7+ pull_request :
8+ branches : [ master ]
9+
10+ permissions :
11+ contents : read
12+ packages : write # needed for GHCR
13+ id-token : write
14+
15+ concurrency :
16+ group : docker-compose-ci-${{ github.ref }}
17+ cancel-in-progress : true
18+
19+ env :
20+ # Project namespace for your image path: ghcr.io/<owner>/<REPO_SLUG>/<service>
21+ REPO_SLUG : centralized-logging
22+ # Optional: set to your Docker Hub namespace (lowercase). Leave empty to skip mirroring.
23+ DOCKERHUB_NAMESPACE : " "
24+ # Multi-arch
25+ PLATFORMS : linux/amd64,linux/arm64
626
727jobs :
8- build :
28+ build-and-push :
929 runs-on : ubuntu-latest
1030
11- env :
12- # Your Docker Hub namespace (must be lowercase)
13- DOCKERHUB_NS : ${{ secrets.DOCKERHUB_USERNAME }}
14-
1531 steps :
1632 - name : Checkout
1733 uses : actions/checkout@v4
1834 with :
1935 fetch-depth : 0
2036
21- - name : Setup Docker Buildx
37+ - name : Set up QEMU
38+ uses : docker/setup-qemu-action@v3
39+
40+ - name : Set up Docker Buildx
2241 uses : docker/setup-buildx-action@v3
2342
24- - name : Login to Docker Hub
25- uses : docker/login-action@v3
43+ # --- Compute tags per service (three separate metadata steps) ---
44+ - name : Meta (userapi)
45+ id : meta_user
46+ uses : docker/metadata-action@v5
2647 with :
27- username : ${{ secrets.DOCKERHUB_USERNAME }}
28- password : ${{ secrets.DOCKERHUB_TOKEN }}
48+ images : ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/userapi
49+ tags : |
50+ type=raw,value=edge,enable=${{ github.event_name != 'pull_request' }}
51+ type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
52+ type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
53+ type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
54+
55+ - name : Meta (api)
56+ id : meta_api
57+ uses : docker/metadata-action@v5
58+ with :
59+ images : ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/api
60+ tags : |
61+ type=raw,value=edge,enable=${{ github.event_name != 'pull_request' }}
62+ type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
63+ type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
64+ type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
65+
66+ - name : Meta (web)
67+ id : meta_web
68+ uses : docker/metadata-action@v5
69+ with :
70+ images : ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/web
71+ tags : |
72+ type=raw,value=edge,enable=${{ github.event_name != 'pull_request' }}
73+ type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
74+ type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
75+ type=semver,pattern={{major}}.{{minor}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
2976
3077 - name : Login to GHCR
78+ if : ${{ github.event_name != 'pull_request' }}
3179 uses : docker/login-action@v3
3280 with :
3381 registry : ghcr.io
34- username : ${{ github.actor }}
82+ username : ${{ github.repository_owner }}
3583 password : ${{ secrets.GITHUB_TOKEN }}
3684
37- - name : Compute short SHA
38- id : sha
39- run : echo "short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
85+ - name : Login to Docker Hub (optional)
86+ if : ${{ github.event_name != 'pull_request' && env.DOCKERHUB_NAMESPACE != '' && secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }}
87+ uses : docker/login-action@v3
88+ with :
89+ username : ${{ secrets.DOCKERHUB_USERNAME }}
90+ password : ${{ secrets.DOCKERHUB_TOKEN }}
4091
41- - name : Ensure compose files exist
42- run : |
43- test -f docker-compose.yml || (echo "missing docker-compose.yml" && exit 1)
44- test -f docker-compose.ci.override.yml || (echo "missing docker-compose.ci.override.yml" && exit 1)
92+ # Build cache (local dir cache)
93+ - name : Restore build cache
94+ uses : actions/cache@v4
95+ with :
96+ path : /tmp/.buildx-cache
97+ key : ${{ runner.os }}-buildx-${{ github.sha }}
98+ restore-keys : |
99+ ${{ runner.os }}-buildx-
45100
46- - name : Build & Push with Bake (compose + override )
101+ - name : Bake & Push (multi-arch )
47102 uses : docker/bake-action@v5
48103 with :
49- files : |
50- docker-compose.yml
51- docker-compose.ci.override.yml
52- push : true
53- # Add extra tags for GHCR (sha) and Docker Hub (edge + sha)
104+ files : ./docker-bake.hcl
105+ push : ${{ github.event_name != 'pull_request' }}
54106 set : |
55- *.labels=org.opencontainers.image.revision=${{ github.sha }}
56- usermanagementapi.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/usermanagementapi:edge
57- usermanagementapi.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/usermanagementapi:${{ steps.sha.outputs.short }}
58- centralizedloggingapi.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/loggingapi:edge
59- centralizedloggingapi.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/loggingapi:${{ steps.sha.outputs.short }}
60- apiintegrationmvc.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/integrationportal:edge
61- apiintegrationmvc.tags=${{ env.DOCKERHUB_NS }}/centralized-logging/integrationportal:${{ steps.sha.outputs.short }}
62- env :
63- # Primary tag selected in the override (GHCR)
64- TAG : edge
107+ # Platforms & cache
108+ *.platform=${{ env.PLATFORMS }}
109+ *.cache-from=type=local,src=/tmp/.buildx-cache
110+ *.cache-to=type=local,dest=/tmp/.buildx-cache-new,mode=max
111+ # Labels/injection
112+ *.labels.org.opencontainers.image.revision=${{ github.sha }}
113+ # Bake variables (must match variable names in docker-bake.hcl)
114+ OWNER=${{ github.repository_owner }}
115+ REPO_SLUG=${{ env.REPO_SLUG }}
116+ # If you customized REGISTRY_GHCR in the bake file, you could set it here too:
117+ # REGISTRY_GHCR=ghcr.io
118+ # Service-specific tags
119+ userapi.tags=${{ steps.meta_user.outputs.tags }}
120+ api.tags=${{ steps.meta_api.outputs.tags }}
121+ web.tags=${{ steps.meta_web.outputs.tags }}
122+
123+ - name : Save build cache
124+ if : always()
125+ run : |
126+ rm -rf /tmp/.buildx-cache
127+ mv /tmp/.buildx-cache-new /tmp/.buildx-cache
128+
129+ - name : Mirror to Docker Hub (optional)
130+ if : ${{ github.event_name != 'pull_request' && env.DOCKERHUB_NAMESPACE != '' && secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }}
131+ run : |
132+ set -euo pipefail
133+ mapfile -t USER_TAGS <<< "${{ steps.meta_user.outputs.tags }}"
134+ mapfile -t API_TAGS <<< "${{ steps.meta_api.outputs.tags }}"
135+ mapfile -t WEB_TAGS <<< "${{ steps.meta_web.outputs.tags }}"
136+
137+ mirror() {
138+ local svc="$1"; shift
139+ for t in "$@"; do
140+ tg="$(basename "$t")"
141+ ghcr="ghcr.io/${{ github.repository_owner }}/${{ env.REPO_SLUG }}/${svc}:${tg}"
142+ hub="${{ env.DOCKERHUB_NAMESPACE }}/${{ env.REPO_SLUG }}-${svc}:${tg}"
143+ echo "Mirroring $ghcr -> $hub"
144+ docker pull "$ghcr"
145+ docker tag "$ghcr" "$hub"
146+ docker push "$hub"
147+ done
148+ }
149+
150+ mirror userapi "${USER_TAGS[@]}"
151+ mirror api "${API_TAGS[@]}"
152+ mirror web "${WEB_TAGS[@]}"
0 commit comments