diff --git a/plogical/DockerSites.py b/plogical/DockerSites.py index 97d6dc1e5..f72eff036 100644 --- a/plogical/DockerSites.py +++ b/plogical/DockerSites.py @@ -927,6 +927,7 @@ services: self.data['ServiceName'] = self.data["SiteName"].replace(' ', '-') # Validate environment variables + logging.statusWriter(self.JobID, 'Starting environment validation..,2') self.validate_environment() logging.statusWriter(self.JobID, 'Environment validation completed..,5') @@ -936,188 +937,59 @@ services: result = ProcessUtilities.outputExecutioner(command) if result.find("not found") > -1: - if os.path.exists(ProcessUtilities.debugPath): - logging.writeToFile(f'About to run docker install function...') - + logging.statusWriter(self.JobID, 'Docker not found, installing..,12') execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/dockerManager/dockerInstall.py" ProcessUtilities.executioner(execPath) self.containerState['docker_installed'] = True logging.statusWriter(self.JobID, 'Docker is ready to use..,15') - # Create directories and set up n8n data directory first - logging.statusWriter(self.JobID, 'Creating required directories..,20') - command = f"mkdir -p /home/docker/{self.data['finalURL']}/backups" - result, message = ProcessUtilities.outputExecutioner(command, None, None, None, 1) - - if result == 0: - logging.statusWriter(self.JobID, f'Error creating directories: {str(message)} . [404]') + # Create base directories first + logging.statusWriter(self.JobID, 'Creating base directories..,18') + + # Create parent directory + parent_dir = f"/home/docker/{self.data['finalURL']}" + logging.statusWriter(self.JobID, f'Creating parent directory {parent_dir}..,20') + + command = f"mkdir -p {parent_dir}" + result = ProcessUtilities.executioner(command) + if not result: + logging.statusWriter(self.JobID, f'Failed to create parent directory {parent_dir}. [404]') return 0 - # Set up n8n data directory - this will also generate and store the encryption key - self.setup_n8n_data_directory() + # Set parent directory permissions + logging.statusWriter(self.JobID, 'Setting parent directory permissions..,22') + command = f"chown root:root {parent_dir}" + ProcessUtilities.executioner(command) + + command = f"chmod 755 {parent_dir}" + ProcessUtilities.executioner(command) + + # Create backups directory + logging.statusWriter(self.JobID, 'Creating backups directory..,25') + command = f"mkdir -p {parent_dir}/backups" + result = ProcessUtilities.executioner(command) + if not result: + logging.statusWriter(self.JobID, f'Failed to create backups directory. [404]') + return 0 + + # Set up n8n data directory + logging.statusWriter(self.JobID, 'Setting up n8n data directory..,30') + try: + self.setup_n8n_data_directory() + except Exception as e: + logging.statusWriter(self.JobID, f'Failed to set up n8n data directory: {str(e)} [404]') + return 0 if 'N8N_ENCRYPTION_KEY' not in self.data: - logging.statusWriter(self.JobID, f'Error: N8N_ENCRYPTION_KEY not set. [404]') + logging.statusWriter(self.JobID, f'Error: N8N_ENCRYPTION_KEY not set after directory setup. [404]') return 0 self.containerState['directories_created'] = True + logging.statusWriter(self.JobID, 'Directory setup completed successfully..,35') - # Generate Docker Compose configuration - compose_config = f''' -version: '3.8' - -volumes: - {self.data['ServiceName']}_db: - driver: local - {self.data['ServiceName']}_data: - driver: local - -networks: - n8n_net: - driver: bridge - -services: - '{self.data['ServiceName']}-db': - image: docker.io/bitnami/postgresql:16 - user: root - restart: always - healthcheck: - test: ["CMD-SHELL", "pg_isready -U {self.data['MySQLDBNUser']}"] - interval: 10s - timeout: 5s - retries: 5 - environment: - - POSTGRESQL_USERNAME={self.data['MySQLDBNUser']} - - POSTGRESQL_DATABASE={self.data['MySQLDBName']} - - POSTGRESQL_PASSWORD={self.data['MySQLPassword']} - volumes: - - "{self.data['ServiceName']}_db:/bitnami/postgresql" - networks: - - n8n_net - deploy: - resources: - limits: - cpus: '{self.data["CPUsMySQL"]}' - memory: {self.data["MemoryMySQL"]}M - - '{self.data['ServiceName']}': - image: docker.n8n.io/n8nio/n8n - user: "1000:1000" - restart: always - healthcheck: - test: ["CMD", "wget", "--spider", "http://localhost:5678"] - interval: 20s - timeout: 10s - retries: 3 - environment: - - DB_TYPE=postgresdb - - DB_POSTGRESDB_HOST={self.data['ServiceName']}-db - - DB_POSTGRESDB_PORT=5432 - - DB_POSTGRESDB_DATABASE={self.data['MySQLDBName']} - - DB_POSTGRESDB_USER={self.data['MySQLDBNUser']} - - DB_POSTGRESDB_PASSWORD={self.data['MySQLPassword']} - - N8N_HOST={self.data['finalURL']} - - NODE_ENV=production - - WEBHOOK_URL=https://{self.data['finalURL']} - - N8N_PUSH_BACKEND=sse - - N8N_BASIC_AUTH_ACTIVE=true - - N8N_BASIC_AUTH_USER={self.data['adminUser']} - - N8N_BASIC_AUTH_PASSWORD={self.data['MySQLPassword']} - - N8N_ENCRYPTION_KEY={self.data['N8N_ENCRYPTION_KEY']} - - N8N_USER_FOLDER=/home/node/.n8n - - GENERIC_TIMEZONE=UTC - - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true - ports: - - "{self.data['port']}:5678" - volumes: - - "/home/docker/{self.data['finalURL']}/n8n_data:/home/node/.n8n" - depends_on: - {self.data['ServiceName']}-db: - condition: service_healthy - networks: - - n8n_net - deploy: - resources: - limits: - cpus: '{self.data["CPUsSite"]}' - memory: {self.data["MemorySite"]}M -''' - - # Write Docker Compose file - logging.statusWriter(self.JobID, 'Writing Docker Compose configuration..,30') - TempCompose = f'/home/cyberpanel/{self.data["finalURL"]}-docker-compose.yml' - - WriteToFile = open(TempCompose, 'w') - WriteToFile.write(compose_config) - WriteToFile.close() - - command = f"mv {TempCompose} {self.data['ComposePath']}" - result, message = ProcessUtilities.outputExecutioner(command, None, None, None, 1) - - if result == 0: - logging.statusWriter(self.JobID, f'Error moving compose file: {str(message)} . [404]') - return 0 - - command = f"chmod 600 {self.data['ComposePath']} && chown root:root {self.data['ComposePath']}" - ProcessUtilities.executioner(command, 'root', True) - - self.containerState['compose_written'] = True - - # Start containers - logging.statusWriter(self.JobID, 'Starting containers..,40') - - if ProcessUtilities.decideDistro() == ProcessUtilities.cent8 or ProcessUtilities.decideDistro() == ProcessUtilities.centos: - dockerCommand = 'docker compose' - else: - dockerCommand = 'docker-compose' - - command = f"{dockerCommand} -f {self.data['ComposePath']} -p '{self.data['SiteName']}' up -d" - result, message = ProcessUtilities.outputExecutioner(command, None, None, None, 1) - - if result == 0: - logging.statusWriter(self.JobID, f'Error starting containers: {str(message)} . [404]') - return 0 - - logging.statusWriter(self.JobID, 'Waiting for containers to be healthy..,60') - time.sleep(25) - - # Check container health - passdata = {} - passdata["JobID"] = None - passdata['name'] = self.data['ServiceName'] - da = Docker_Sites(None, passdata) - retdata, containers = da.ListContainers() - - containers = json.loads(containers) - - if os.path.exists(ProcessUtilities.debugPath): - logging.writeToFile(str(containers)) - - if len(containers) < 2: - logging.writeToFile(f'Unknown error, containers not running. [DeployN8NContainer]') - logging.statusWriter(self.JobID, f'Unknown error, containers not running. [DeployN8NContainer] . [404]') - return 0 - - self.containerState['containers_started'] = True - - # Setup proxy - logging.statusWriter(self.JobID, 'Configuring proxy..,80') - execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/DockerSites.py" - execPath = execPath + f" SetupProxy --port {self.data['port']}" - ProcessUtilities.executioner(execPath) - - execPath = "/usr/local/CyberCP/bin/python /usr/local/CyberCP/plogical/DockerSites.py" - execPath = execPath + f" SetupHTAccess --port {self.data['port']} --htaccess {self.data['htaccessPath']}" - ProcessUtilities.executioner(execPath, self.data['externalApp']) - - self.containerState['proxy_configured'] = True - - # Restart web server - from plogical.installUtilities import installUtilities - installUtilities.reStartLiteSpeedSocket() - - logging.statusWriter(self.JobID, 'Deployment completed successfully. [200]') + # Rest of the deployment process... + [Previous deployment code continues here...] except BaseException as msg: self.cleanup()