diff --git a/static/js/launch_progress.js b/static/js/launch_progress.js
index 26fe373..276dcf4 100644
--- a/static/js/launch_progress.js
+++ b/static/js/launch_progress.js
@@ -1,3 +1,17 @@
+/**
+ * Launch Progress JavaScript
+ *
+ * This file handles the instance launch and update process, including:
+ * - Step-by-step progress tracking
+ * - Stack deployment via Portainer API
+ * - Error handling for HTTP 502/504 responses
+ *
+ * Note: HTTP 502 (Bad Gateway) and 504 (Gateway Timeout) errors are treated as
+ * potential success cases since they often occur when Portainer is busy but the
+ * operation may still succeed. In these cases, the system continues monitoring
+ * the stack status.
+ */
+
document.addEventListener('DOMContentLoaded', function() {
// Check if this is an update operation
if (window.isUpdate && window.updateInstanceId && window.updateRepoId && window.updateBranch) {
@@ -561,6 +575,11 @@ async function startLaunch(data) {
Initiating stack deployment...
+
+
+ Note: Stack deployment can take several minutes. If you see HTTP 502 or 504 errors,
+ the deployment may still be in progress and will be monitored automatically.
+
`;
stackDeployStepElement.querySelector('.step-content').appendChild(stackProgressDiv);
@@ -2923,6 +2942,15 @@ async function deployStack(dockerComposeContent, stackName, port) {
console.log('Response status:', response.status);
console.log('Response ok:', response.ok);
console.log('Response headers:', Object.fromEntries(response.headers.entries()));
+
+ // Log additional response details for debugging
+ if (response.status === 502) {
+ console.log('HTTP 502 Bad Gateway detected - this usually means Portainer is busy or slow to respond');
+ console.log('The stack deployment may still be in progress despite this error');
+ } else if (response.status === 504) {
+ console.log('HTTP 504 Gateway Timeout detected - the request took too long');
+ console.log('This is expected for long-running stack deployments');
+ }
// Handle 504 Gateway Timeout as successful initiation
if (response.status === 504) {
@@ -2947,6 +2975,29 @@ async function deployStack(dockerComposeContent, stackName, port) {
let errorMessage = 'Failed to deploy stack';
console.log('Response not ok, status:', response.status);
+ // Handle 502 Bad Gateway and 504 Gateway Timeout as potential success cases
+ // These errors often occur when Portainer is busy or slow to respond, but the operation may still succeed
+ if (response.status === 502 || response.status === 504) {
+ console.log(`Received HTTP ${response.status} - stack creation may still be in progress`);
+ console.log('HTTP 502 (Bad Gateway) typically means Portainer is busy or slow to respond');
+ console.log('HTTP 504 (Gateway Timeout) means the request took too long');
+ console.log('In both cases, we continue monitoring since the operation may still succeed');
+
+ // Update progress to show that we're now polling
+ const progressBar = document.getElementById('launchProgress');
+ const progressText = document.getElementById('stepDescription');
+ if (progressBar && progressText) {
+ progressBar.style.width = '25%';
+ progressBar.textContent = '25%';
+ progressText.textContent = `Stack creation initiated (HTTP ${response.status}, but continuing to monitor)...`;
+ }
+
+ // Start polling immediately since the stack creation was initiated
+ console.log(`Starting to poll for stack status after HTTP ${response.status}...`);
+ const pollResult = await pollStackStatus(stackName, 15 * 60 * 1000); // 15 minutes max
+ return pollResult;
+ }
+
try {
const errorData = await response.json();
errorMessage = errorData.error || errorMessage;
@@ -3004,13 +3055,15 @@ async function deployStack(dockerComposeContent, stackName, port) {
} catch (error) {
console.error('Error deploying stack:', error);
- // Check if this is a 504 timeout error that should be handled as a success
+ // Check if this is a 502 or 504 error that should be handled as a success
if (error.message && (
error.message.includes('504 Gateway Time-out') ||
error.message.includes('504 Gateway Timeout') ||
- error.message.includes('timed out')
+ error.message.includes('timed out') ||
+ error.message.includes('502') ||
+ error.message.includes('Bad Gateway')
)) {
- console.log('Detected 504 timeout in catch block - treating as successful initiation');
+ console.log('Detected HTTP 502/504 error in catch block - treating as successful initiation');
// Update progress to show that we're now polling
const progressBar = document.getElementById('launchProgress');
@@ -3018,11 +3071,11 @@ async function deployStack(dockerComposeContent, stackName, port) {
if (progressBar && progressText) {
progressBar.style.width = '25%';
progressBar.textContent = '25%';
- progressText.textContent = 'Stack creation initiated (timed out, but continuing to monitor)...';
+ progressText.textContent = 'Stack creation initiated (HTTP error, but continuing to monitor)...';
}
// Start polling immediately since the stack creation was initiated
- console.log('Starting to poll for stack status after 504 timeout from catch block...');
+ console.log('Starting to poll for stack status after HTTP 502/504 error from catch block...');
const pollResult = await pollStackStatus(stackName, 15 * 60 * 1000); // 15 minutes max
return pollResult;
}
@@ -3279,6 +3332,25 @@ async function updateStack(dockerComposeContent, stackId, port, instanceData = n
let errorMessage = 'Failed to update stack';
console.log('Response not ok, status:', response.status);
+ // Handle 502 Bad Gateway and 504 Gateway Timeout as potential success cases
+ if (response.status === 502 || response.status === 504) {
+ console.log(`Received HTTP ${response.status} - stack update may still be in progress`);
+
+ // Update progress to show that we're now polling
+ const progressBar = document.getElementById('launchProgress');
+ const progressText = document.getElementById('stepDescription');
+ if (progressBar && progressText) {
+ progressBar.style.width = '25%';
+ progressBar.textContent = '25%';
+ progressText.textContent = `Stack update initiated (HTTP ${response.status}, but continuing to monitor)...`;
+ }
+
+ // Start polling immediately since the stack update was initiated
+ console.log(`Starting to poll for stack status after HTTP ${response.status}...`);
+ const pollResult = await pollStackStatus(stackId, 15 * 60 * 1000); // 15 minutes max
+ return pollResult;
+ }
+
try {
const errorData = await response.json();
errorMessage = errorData.error || errorMessage;
@@ -3336,13 +3408,15 @@ async function updateStack(dockerComposeContent, stackId, port, instanceData = n
} catch (error) {
console.error('Error updating stack:', error);
- // Check if this is a 504 timeout error that should be handled as a success
+ // Check if this is a 502 or 504 error that should be handled as a success
if (error.message && (
error.message.includes('504 Gateway Time-out') ||
error.message.includes('504 Gateway Timeout') ||
- error.message.includes('timed out')
+ error.message.includes('timed out') ||
+ error.message.includes('502') ||
+ error.message.includes('Bad Gateway')
)) {
- console.log('Detected 504 timeout in catch block - treating as successful initiation');
+ console.log('Detected HTTP 502/504 error in catch block - treating as successful initiation');
// Update progress to show that we're now polling
const progressBar = document.getElementById('launchProgress');
@@ -3350,11 +3424,11 @@ async function updateStack(dockerComposeContent, stackId, port, instanceData = n
if (progressBar && progressText) {
progressBar.style.width = '25%';
progressBar.textContent = '25%';
- progressText.textContent = 'Stack update initiated (timed out, but continuing to monitor)...';
+ progressText.textContent = 'Stack update initiated (HTTP error, but continuing to monitor)...';
}
// Start polling immediately since the stack update was initiated
- console.log('Starting to poll for stack status after 504 timeout from catch block...');
+ console.log('Starting to poll for stack status after HTTP 502/504 error from catch block...');
const pollResult = await pollStackStatus(stackId, 15 * 60 * 1000); // 15 minutes max
return pollResult;
}