useDocker.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. if ('flame.icon' in labels) {
  81. icons = labels['flame.icon'].split(';');
  82. }
  83. dockerApps.push({
  84. name: names[i] || names[0],
  85. url: urls[i] || urls[0],
  86. icon: icons[i] || 'docker',
  87. });
  88. }
  89. }
  90. }
  91. if (unpinStoppedApps) {
  92. for (const app of apps) {
  93. await app.update({ isPinned: false });
  94. }
  95. }
  96. for (const item of dockerApps) {
  97. // If app already exists, update it
  98. if (apps.some((app) => app.name === item.name)) {
  99. const app = apps.find((a) => a.name === item.name);
  100. if (
  101. item.icon === 'custom' ||
  102. (item.icon === 'docker' && app.icon != 'docker')
  103. ) {
  104. // update without overriding icon
  105. await app.update({
  106. name: item.name,
  107. url: item.url,
  108. isPinned: true,
  109. });
  110. } else {
  111. await app.update({
  112. ...item,
  113. isPinned: true,
  114. });
  115. }
  116. } else {
  117. // else create new app
  118. await App.create({
  119. ...item,
  120. icon: item.icon === 'custom' ? 'docker' : item.icon,
  121. isPinned: true,
  122. });
  123. }
  124. }
  125. }
  126. };
  127. module.exports = useDocker;