diff --git a/plogical/DockerSites.py b/plogical/DockerSites.py index f72eff036..93a283e07 100644 --- a/plogical/DockerSites.py +++ b/plogical/DockerSites.py @@ -944,21 +944,34 @@ services: self.containerState['docker_installed'] = True logging.statusWriter(self.JobID, 'Docker is ready to use..,15') - # Create base directories first - logging.statusWriter(self.JobID, 'Creating base directories..,18') + # Create and setup base docker directory first + logging.statusWriter(self.JobID, 'Setting up base docker directory..,18') - # Create parent directory + # Create /home/docker if it doesn't exist + command = "mkdir -p /home/docker" + result = ProcessUtilities.executioner(command) + if not result: + logging.statusWriter(self.JobID, 'Failed to create base docker directory. [404]') + return 0 + + # Set proper permissions on base docker directory + command = "chown root:root /home/docker" + ProcessUtilities.executioner(command) + + command = "chmod 755 /home/docker" + ProcessUtilities.executioner(command) + + # Create site-specific directory parent_dir = f"/home/docker/{self.data['finalURL']}" - logging.statusWriter(self.JobID, f'Creating parent directory {parent_dir}..,20') + logging.statusWriter(self.JobID, f'Creating site 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]') + logging.statusWriter(self.JobID, f'Failed to create site directory {parent_dir}. [404]') return 0 - # Set parent directory permissions - logging.statusWriter(self.JobID, 'Setting parent directory permissions..,22') + # Set site directory permissions command = f"chown root:root {parent_dir}" ProcessUtilities.executioner(command) @@ -973,6 +986,13 @@ services: logging.statusWriter(self.JobID, f'Failed to create backups directory. [404]') return 0 + # Set backups directory permissions + command = f"chown root:root {parent_dir}/backups" + ProcessUtilities.executioner(command) + + command = f"chmod 755 {parent_dir}/backups" + ProcessUtilities.executioner(command) + # Set up n8n data directory logging.statusWriter(self.JobID, 'Setting up n8n data directory..,30') try: @@ -988,8 +1008,156 @@ services: self.containerState['directories_created'] = True logging.statusWriter(self.JobID, 'Directory setup completed successfully..,35') - # Rest of the deployment process... - [Previous deployment code continues here...] + # 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..,40') + 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 = ProcessUtilities.executioner(command) + if not result: + logging.statusWriter(self.JobID, f'Failed to move compose file to final location. [404]') + return 0 + + command = f"chmod 600 {self.data['ComposePath']} && chown root:root {self.data['ComposePath']}" + ProcessUtilities.executioner(command) + + self.containerState['compose_written'] = True + + # Start containers + logging.statusWriter(self.JobID, 'Starting containers..,50') + + 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 = ProcessUtilities.executioner(command) + if not result: + logging.statusWriter(self.JobID, f'Failed to start containers. [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 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]') except BaseException as msg: self.cleanup()