useDocker.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. const App = require('../../../models/App');
  2. const axios = require('axios');
  3. const Logger = require('../../../utils/Logger');
  4. const logger = new Logger();
  5. const loadConfig = require('../../../utils/loadConfig');
  6. const useDocker = async (apps) => {
  7. const {
  8. useOrdering: orderType,
  9. unpinStoppedApps,
  10. dockerHost: host,
  11. } = await loadConfig();
  12. let containers = null;
  13. // Get list of containers
  14. try {
  15. if (host.includes('localhost')) {
  16. // Use default host
  17. let { data } = await axios.get(
  18. `http://${host}/containers/json?{"status":["running"]}`,
  19. {
  20. socketPath: '/var/run/docker.sock',
  21. }
  22. );
  23. containers = data;
  24. } else {
  25. // Use custom host
  26. let { data } = await axios.get(
  27. `http://${host}/containers/json?{"status":["running"]}`
  28. );
  29. containers = data;
  30. }
  31. } catch {
  32. logger.log(`Can't connect to the Docker API on ${host}`, 'ERROR');
  33. }
  34. if (containers) {
  35. apps = await App.findAll({
  36. order: [[orderType, 'ASC']],
  37. });
  38. // Filter out containers without any annotations
  39. containers = containers.filter((e) => Object.keys(e.Labels).length !== 0);
  40. const dockerApps = [];
  41. for (const container of containers) {
  42. let labels = container.Labels;
  43. // Traefik labels for URL configuration
  44. if (!('flame.url' in labels)) {
  45. for (const label of Object.keys(labels)) {
  46. if (/^traefik.*.frontend.rule/.test(label)) {
  47. // Traefik 1.x
  48. let value = labels[label];
  49. if (value.indexOf('Host') !== -1) {
  50. value = value.split('Host:')[1];
  51. labels['flame.url'] =
  52. 'https://' + value.split(',').join(';https://');
  53. }
  54. } else if (/^traefik.*?\.rule/.test(label)) {
  55. // Traefik 2.x
  56. const value = labels[label];
  57. if (value.indexOf('Host') !== -1) {
  58. const regex = /\`([a-zA-Z0-9\.\-]+)\`/g;
  59. const domains = [];
  60. while ((match = regex.exec(value)) != null) {
  61. domains.push('http://' + match[1]);
  62. }
  63. if (domains.length > 0) {
  64. labels['flame.url'] = domains.join(';');
  65. }
  66. }
  67. }
  68. }
  69. }
  70. // add each container as flame formatted app
  71. if (
  72. 'flame.name' in labels &&
  73. 'flame.url' in labels &&
  74. /^app/.test(labels['flame.type'])
  75. ) {
  76. for (let i = 0; i < labels['flame.name'].split(';').length; i++) {
  77. const names = labels['flame.name'].split(';');
  78. const urls = labels['flame.url'].split(';');
  79. let icons = '';
  80. let descriptions = '';
  81. let visibility = '';
  82. if ('flame.icon' in labels) {
  83. icons = labels['flame.icon'].split(';');
  84. }
  85. if ('flame.description' in labels) {
  86. descriptions = labels['flame.description'].split(';');
  87. }
  88. if ('flame.visible' in labels) {
  89. visibility = labels['flame.visible'].split(';');
  90. }
  91. dockerApps.push({
  92. name: names[i] || names[0],
  93. url: urls[i] || urls[0],
  94. icon: icons[i] || 'docker',
  95. // Add description and visbility
  96. description: descriptions[i] || '',
  97. isPublic: (visibility[i] && /^true$/.test(visibility[i]) ? visibility[i] : visibility[0]) || null,
  98. });
  99. }
  100. }
  101. }
  102. if (unpinStoppedApps) {
  103. for (const app of apps) {
  104. await app.update({ isPinned: false });
  105. }
  106. }
  107. for (const item of dockerApps) {
  108. // If app already exists, update it
  109. // Find by name or url
  110. if (apps.some((app) => app.name === item.name || app.url === item.url)) {
  111. const app = apps.find((a) => a.name === item.name || app.url === item.url);
  112. if (
  113. item.icon === 'custom' ||
  114. (item.icon === 'docker' && app.icon != 'docker')
  115. ) {
  116. // update without overriding icon
  117. await app.update({
  118. name: item.name,
  119. url: item.url,
  120. // Add description and visbility
  121. description: item.description,
  122. isPublic: item.isPublic,
  123. isPinned: true,
  124. });
  125. } else {
  126. await app.update({
  127. ...item,
  128. isPinned: true,
  129. });
  130. }
  131. } else {
  132. // else create new app
  133. await App.create({
  134. ...item,
  135. icon: item.icon === 'custom' ? 'docker' : item.icon,
  136. isPinned: true,
  137. });
  138. }
  139. }
  140. }
  141. };
  142. module.exports = useDocker;