@@ -50,6 +50,7 @@ class ApplicationDeploymentJob implements ShouldQueue
50
50
private ApplicationPreview |null $ preview = null ;
51
51
52
52
private string $ container_name ;
53
+ private string |null $ currently_running_container_name = null ;
53
54
private string $ workdir ;
54
55
private string $ configuration_dir ;
55
56
private string $ build_workdir ;
@@ -86,7 +87,7 @@ public function __construct(int $application_deployment_queue_id)
86
87
$ this ->build_workdir = "{$ this ->workdir }" . rtrim ($ this ->application ->base_directory , '/ ' );
87
88
$ this ->is_debug_enabled = $ this ->application ->settings ->is_debug_enabled ;
88
89
89
- $ this ->container_name = generate_container_name ($ this ->application ->uuid , $ this ->pull_request_id );
90
+ $ this ->container_name = generateApplicationContainerName ($ this ->application ->uuid , $ this ->pull_request_id );
90
91
$ this ->private_key_location = save_private_key_for_server ($ this ->server );
91
92
$ this ->saved_outputs = collect ();
92
93
@@ -113,6 +114,10 @@ public function __construct(int $application_deployment_queue_id)
113
114
public function handle (): void
114
115
{
115
116
// ray()->measure();
117
+ $ containers = getCurrentApplicationContainerStatus ($ this ->server , $ this ->application ->id );
118
+ if ($ containers ->count () > 0 ) {
119
+ $ this ->currently_running_container_name = data_get ($ containers [0 ], 'Names ' );
120
+ }
116
121
$ this ->application_deployment_queue ->update ([
117
122
'status ' => ApplicationDeploymentStatus::IN_PROGRESS ->value ,
118
123
]);
@@ -175,9 +180,9 @@ private function deploy_simple_dockerfile()
175
180
$ this ->generate_build_env_variables ();
176
181
$ this ->add_build_env_variables_to_dockerfile ();
177
182
$ this ->build_image ();
178
- $ this ->stop_running_container ();
179
- $ this ->start_by_compose_file ();
183
+ $ this ->rolling_update ();
180
184
}
185
+
181
186
private function deploy ()
182
187
{
183
188
$ this ->execute_remote_command (
@@ -206,8 +211,7 @@ private function deploy()
206
211
"echo 'Docker Image found locally with the same Git Commit SHA {$ this ->application ->uuid }: {$ this ->commit }. Build step skipped...' "
207
212
]);
208
213
$ this ->generate_compose_file ();
209
- $ this ->stop_running_container ();
210
- $ this ->start_by_compose_file ();
214
+ $ this ->rolling_update ();
211
215
return ;
212
216
}
213
217
}
@@ -219,8 +223,54 @@ private function deploy()
219
223
$ this ->generate_build_env_variables ();
220
224
$ this ->add_build_env_variables_to_dockerfile ();
221
225
$ this ->build_image ();
222
- $ this ->stop_running_container ();
226
+ $ this ->rolling_update ();
227
+ }
228
+
229
+ private function rolling_update ()
230
+ {
223
231
$ this ->start_by_compose_file ();
232
+ $ this ->health_check ();
233
+ $ this ->stop_running_container ();
234
+ }
235
+ private function health_check ()
236
+ {
237
+ ray ('New container name: ' ,$ this ->container_name );
238
+ if ($ this ->container_name ) {
239
+ $ counter = 0 ;
240
+ $ this ->execute_remote_command (
241
+ [
242
+ "echo 'Waiting for health check to pass on the new version of your application.' "
243
+ ],
244
+ );
245
+ while ($ counter < $ this ->application ->health_check_retries ) {
246
+ $ this ->execute_remote_command (
247
+ [
248
+ "echo 'Attempt {$ counter } of {$ this ->application ->health_check_retries }' "
249
+ ],
250
+ [
251
+ "docker inspect --format='{{json .State.Health.Status}}' {$ this ->container_name }" ,
252
+ "hidden " => true ,
253
+ "save " => "health_check "
254
+ ],
255
+
256
+ );
257
+ $ this ->execute_remote_command (
258
+ [
259
+ "echo 'New application version health check status: {$ this ->saved_outputs ->get ('health_check ' )}' "
260
+ ],
261
+ );
262
+ if (Str::of ($ this ->saved_outputs ->get ('health_check ' ))->contains ('healthy ' )) {
263
+ $ this ->execute_remote_command (
264
+ [
265
+ "echo 'Rolling update completed.' "
266
+ ],
267
+ );
268
+ break ;
269
+ }
270
+ $ counter ++;
271
+ sleep ($ this ->application ->health_check_interval );
272
+ }
273
+ }
224
274
}
225
275
private function deploy_pull_request ()
226
276
{
@@ -241,8 +291,7 @@ private function deploy_pull_request()
241
291
// $this->generate_build_env_variables();
242
292
// $this->add_build_env_variables_to_dockerfile();
243
293
$ this ->build_image ();
244
- $ this ->stop_running_container ();
245
- $ this ->start_by_compose_file ();
294
+ $ this ->rolling_update ();
246
295
}
247
296
248
297
private function prepare_builder_image ()
@@ -409,7 +458,7 @@ private function generate_compose_file()
409
458
$ this ->container_name => [
410
459
'image ' => $ this ->production_image_name ,
411
460
'container_name ' => $ this ->container_name ,
412
- 'restart ' => ' always ' ,
461
+ 'restart ' => RESTART_MODE ,
413
462
'environment ' => $ environment_variables ,
414
463
'labels ' => $ this ->set_labels_for_applications (),
415
464
'expose ' => $ ports ,
@@ -539,8 +588,8 @@ private function set_labels_for_applications()
539
588
$ schema = $ url ->getScheme ();
540
589
$ slug = Str::slug ($ host . $ path );
541
590
542
- $ http_label = "{$ this ->application -> uuid }- {$ slug }-http " ;
543
- $ https_label = "{$ this ->application -> uuid }- {$ slug }-https " ;
591
+ $ http_label = "{$ this ->container_name }- {$ slug }-http " ;
592
+ $ https_label = "{$ this ->container_name }- {$ slug }-https " ;
544
593
545
594
if ($ schema === 'https ' ) {
546
595
// Set labels for https
@@ -647,23 +696,22 @@ private function build_image()
647
696
648
697
private function stop_running_container ()
649
698
{
650
- $ this ->execute_remote_command (
651
- ["echo -n 'Removing old running application.' " ],
652
- [$ this ->execute_in_builder ("docker rm -f $ this ->container_name >/dev/null 2>&1 " ), "hidden " => true ],
653
- );
699
+ if ($ this ->currently_running_container_name ) {
700
+ $ this ->execute_remote_command (
701
+ ["echo -n 'Removing old application version.' " ],
702
+ [$ this ->execute_in_builder ("docker rm -f $ this ->currently_running_container_name >/dev/null 2>&1 " ), "hidden " => true ],
703
+ );
704
+ }
654
705
}
655
706
656
707
private function start_by_compose_file ()
657
708
{
658
709
$ this ->execute_remote_command (
659
- ["echo -n 'Starting new application... ' " ],
710
+ ["echo -n 'Rolling update started. ' " ],
660
711
[$ this ->execute_in_builder ("docker compose --project-directory {$ this ->workdir } up -d >/dev/null " ), "hidden " => true ],
661
- ["echo 'Done. 🎉' " ],
662
712
);
663
713
}
664
714
665
-
666
-
667
715
private function generate_build_env_variables ()
668
716
{
669
717
$ this ->build_args = collect (["--build-arg SOURCE_COMMIT= {$ this ->commit }" ]);
0 commit comments