-
Notifications
You must be signed in to change notification settings - Fork 8.8k
401 lines (369 loc) · 17.6 KB
/
docker-build.yml
File metadata and controls
401 lines (369 loc) · 17.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
name: Docker Build and Push
run-name: Docker Build and Push @${{ inputs.release_type }} by @${{ github.actor }}
on:
workflow_call:
inputs:
main_version:
required: true
type: string
description: "Main version to tag images with. Required for both main and base releases."
base_version:
required: false
type: string
description: "Base version to tag images with. Required for base release type."
release_type:
required: true
type: string
description: "Release type. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base', 'main-all', 'nightly-main-all'."
pre_release:
required: false
type: boolean
default: false
ref:
required: false
type: string
description: "Ref to check out. If not specified, will default to the main version or current branch."
warning_check:
required: true
type: boolean
description: "Warning - use docker-build-v2 unless you have a very valid reason for using this deprecated workflow. By setting to True, you acknowledge all risks of using a possibly breaking workflow."
default: false
workflow_dispatch:
inputs:
main_version:
description: "Main version to tag images with. Required for both main and base releases."
required: false
type: string
base_version:
description: "Base version to tag images with. Required for base release type."
required: false
type: string
release_type:
description: "Type of release. One of 'main', 'main-ep', 'base', 'nightly-main', 'nightly-base', 'main-all', 'nightly-main-all'."
required: true
type: string
pre_release:
description: "Whether this is a pre-release."
required: false
type: boolean
default: false
ref:
required: false
type: string
description: "Ref to check out. If not specified, will default to the main version or current branch."
warning_check:
description: "Warning - use docker-build-v2 unless you have a very valid reason for using this deprecated workflow. By setting to True, you acknowledge all risks of using a possibly breaking workflow."
required: true
type: boolean
default: false
env:
PYTHON_VERSION: "3.13"
TEST_TAG: "langflowai/langflow:test"
jobs:
get-version:
name: Get Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get-version-input.outputs.version || steps.get-version-base.outputs.version || steps.get-version-main.outputs.version }}
steps:
- name: Verify warning check
run: |
if [[ "${{ inputs.warning_check }}" == "false" ]]; then
echo "Warning - use docker-build-v2 unless you have a very valid reason for using this deprecated workflow. By setting to True, you acknowledge all risks of using a possibly breaking workflow."
exit 1
else
echo "User has acknowledged the risks of using this deprecated workflow. Proceeding with build."
fi
- name: Verify a main version exists
if: ${{ inputs.main_version == '' }}
run: |
# due to our how we split packages, we need to have a main version to check out.
echo "Must specify a main version to check out."
exit 1
- name: Check out the code at a specific ref
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
persist-credentials: true
- name: Get Version to Tag
if: ${{ inputs.main_version != '' }}
id: get-version-input
run: |
# Produces the versions we will use to tag the docker images with.
if [[ "${{ inputs.release_type }}" == "base" && "${{ inputs.base_version }}" == '' ]]; then
echo "Must specify a base version for base release type."
exit 1
fi
if [[ "${{ inputs.release_type }}" == "nightly-base" && "${{ inputs.base_version }}" == '' ]]; then
echo "Must specify a base version for nightly-base release type."
exit 1
fi
if [[ ("${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "main-all") && "${{ inputs.main_version }}" == '' ]]; then
echo "Must specify a main version for main release type."
exit 1
fi
if [[ "${{ inputs.release_type }}" == "main-ep" && "${{ inputs.main_version }}" == '' ]]; then
echo "Must specify a main version for main-ep release type."
exit 1
fi
if [[ ("${{ inputs.release_type }}" == "nightly-main" || "${{ inputs.release_type }}" == "nightly-main-all") && "${{ inputs.main_version }}" == '' ]]; then
echo "Must specify a main version for nightly-main release type."
exit 1
fi
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
version=${{ inputs.base_version }}
echo "base version=${{ inputs.base_version }}"
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "main-ep" || "${{ inputs.release_type }}" == "nightly-main" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then
version=${{ inputs.main_version }}
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
else
echo "No version or ref specified. Exiting the workflow."
exit 1
fi
- name: Get Version Base
if: ${{ inputs.base_version == '' && (inputs.release_type == 'base' || inputs.release_type == 'nightly-base') }}
id: get-version-base
run: |
version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//' | head -n 1)
if [ -z "$version" ]; then
echo "Failed to extract version from uv tree output"
exit 1
fi
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
- name: Get Version Main
if: ${{ inputs.main_version == '' && (inputs.release_type == 'main' || inputs.release_type == 'main-ep' || inputs.release_type == 'nightly-main' || inputs.release_type == 'main-all' || inputs.release_type == 'nightly-main-all') }}
id: get-version-main
run: |
version=$(uv tree | grep 'langflow' | grep -v 'langflow-base' | grep -v 'langflow-sdk' | awk '{print $2}' | sed 's/^v//')
echo version=$version
echo version=$version >> $GITHUB_OUTPUT
setup:
runs-on: ubuntu-latest
needs: get-version
outputs:
docker_tags: ${{ steps.set-vars.outputs.docker_tags }}
ghcr_tags: ${{ steps.set-vars.outputs.ghcr_tags }}
file: ${{ steps.set-vars.outputs.file }}
steps:
- name: Set Dockerfile and Tags
id: set-vars
run: |
nightly_suffix=''
if [[ "${{ inputs.release_type }}" == "nightly-base" || "${{ inputs.release_type }}" == "nightly-main" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then
nightly_suffix="-nightly"
fi
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
# LANGFLOW-BASE RELEASE
echo "docker_tags=langflowai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:base-${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:base-latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_base.Dockerfile" >> $GITHUB_OUTPUT
else
if [[ "${{ inputs.pre_release }}" == "true" ]]; then
# LANGFLOW-MAIN PRE-RELEASE
echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }}" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main-ep" ]]; then
# LANGFLOW-MAIN (ENTRYPOINT) RELEASE
echo "docker_tags=langflowai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-ep${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_ep.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main" || "${{ inputs.release_type }}" == "nightly-main" ]]; then
# LANGFLOW-MAIN RELEASE
echo "docker_tags=langflowai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push.Dockerfile" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_type }}" == "main-all" || "${{ inputs.release_type }}" == "nightly-main-all" ]]; then
# LANGFLOW-MAIN (ALL OPTIONAL DEPS) RELEASE
echo "docker_tags=langflowai/langflow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},langflowai/langflow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "ghcr_tags=ghcr.io/langflow-ai/langflow-all${nightly_suffix}:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-all${nightly_suffix}:latest" >> $GITHUB_OUTPUT
echo "file=./docker/build_and_push_with_extras.Dockerfile" >> $GITHUB_OUTPUT
else
echo "Invalid release type. Exiting the workflow."
exit 1
fi
fi
build:
runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-40gb-ephemeral]
needs: [get-version, setup]
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
persist-credentials: true
- name: "Setup Environment"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: ${{ env.PYTHON_VERSION }}
prune-cache: false
- name: Install the project
run: |
if [[ "${{ inputs.release_type }}" == "base" || "${{ inputs.release_type }}" == "nightly-base" ]]; then
uv sync --directory src/backend/base --no-dev --no-sources
else
uv sync --no-dev --no-sources
fi
- name: Docker System Info and Cleanup
run: |
echo "=== Docker System Usage Before Cleanup ==="
docker system df || true
docker buildx du || true
echo "=== Cleaning up Docker System ==="
docker system prune -af --volumes || true
docker buildx prune -af || true
echo "=== Docker System Usage After Cleanup ==="
docker system df || true
docker buildx du || true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver: docker-container
driver-opts: |
image=moby/buildkit:v0.22.0
network=host
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push to Docker Hub
uses: Wandalen/wretry.action@master
with:
action: docker/build-push-action@v6
with: |
context: .
push: true
file: ${{ needs.setup.outputs.file }}
tags: ${{ needs.setup.outputs.docker_tags }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Login to Github Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.TEMP_GHCR_TOKEN}}
- name: Build and push to Github Container Registry
uses: Wandalen/wretry.action@master
with:
action: docker/build-push-action@v6
with: |
context: .
push: true
file: ${{ needs.setup.outputs.file }}
tags: ${{ needs.setup.outputs.ghcr_tags }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build_components:
if: ${{ inputs.release_type == 'main' }}
runs-on: [self-hosted, linux, ARM64, langflow-ai-arm64-40gb-ephemeral]
permissions:
packages: write
needs: [build, get-version]
strategy:
matrix:
component:
[docker-backend, docker-frontend, ghcr-backend, ghcr-frontend]
include:
- component: docker-backend
dockerfile: ./docker/build_and_push_backend.Dockerfile
tags: langflowai/langflow-backend:${{ needs.get-version.outputs.version }},langflowai/langflow-backend:latest
langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
- component: docker-frontend
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
tags: langflowai/langflow-frontend:${{ needs.get-version.outputs.version }},langflowai/langflow-frontend:latest
langflow_image: langflowai/langflow:${{ needs.get-version.outputs.version }}
- component: ghcr-backend
dockerfile: ./docker/build_and_push_backend.Dockerfile
tags: ghcr.io/langflow-ai/langflow-backend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-backend:latest
langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
- component: ghcr-frontend
dockerfile: ./docker/frontend/build_and_push_frontend.Dockerfile
tags: ghcr.io/langflow-ai/langflow-frontend:${{ needs.get-version.outputs.version }},ghcr.io/langflow-ai/langflow-frontend:latest
langflow_image: ghcr.io/langflow-ai/langflow:${{ needs.get-version.outputs.version }}
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
- name: Docker System Info and Cleanup
run: |
echo "=== Docker System Usage Before Cleanup ==="
docker system df || true
docker buildx du || true
echo "=== Cleaning up Docker System ==="
docker system prune -af --volumes || true
docker buildx prune -af || true
echo "=== Docker System Usage After Cleanup ==="
docker system df || true
docker buildx du || true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
driver: docker-container
driver-opts: |
image=moby/buildkit:v0.22.0
network=host
- name: Login to Docker Hub
if: ${{ matrix.component == 'docker-backend' }} || ${{ matrix.component == 'docker-frontend' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Github Container Registry
if: ${{ matrix.component == 'ghcr-backend' }} || ${{ matrix.component == 'ghcr-frontend' }}
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.TEMP_GHCR_TOKEN}}
- name: Wait for propagation (for backend)
run: sleep 120
- name: Build and push ${{ matrix.component }}
uses: Wandalen/wretry.action@master
with:
action: docker/build-push-action@v6
with: |
context: .
push: true
build-args: |
LANGFLOW_IMAGE=${{ matrix.langflow_image }}
file: ${{ matrix.dockerfile }}
tags: ${{ matrix.tags }}
# provenance: false will result in a single manifest for all platforms which makes the image pullable from arm64 machines via the emulation (e.g. Apple Silicon machines)
provenance: false
restart-space:
name: Restart HuggingFace Spaces
if: ${{ inputs.release_type == 'main' }}
runs-on: ubuntu-latest
needs: [build, get-version]
strategy:
matrix:
python-version:
- "3.13"
steps:
- name: Check out the code at a specific ref
uses: actions/checkout@v6
with:
ref: ${{ inputs.ref || inputs.main_version || github.ref }}
- name: "Setup Environment"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
python-version: ${{ matrix.python-version }}
prune-cache: false
- name: Restart HuggingFace Spaces Build
run: |
uv run ./scripts/factory_restart_space.py --space "Langflow/Langflow" --token ${{ secrets.HUGGINGFACE_API_TOKEN }}