mirror of
https://github.com/pawelmalak/flame.git
synced 2024-12-19 08:02:16 +03:00
docker api
This commit is contained in:
parent
b5ba9856ed
commit
b53509aa69
15
README.md
15
README.md
@ -74,6 +74,7 @@ services:
|
|||||||
container_name: flame
|
container_name: flame
|
||||||
volumes:
|
volumes:
|
||||||
- <host_dir>:/app/data
|
- <host_dir>:/app/data
|
||||||
|
- /var/run/docker.sock:/var/sock/docker.sock # Docker socket
|
||||||
ports:
|
ports:
|
||||||
- 5005:5005
|
- 5005:5005
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@ -155,6 +156,20 @@ To use search bar you need to type your search query with selected prefix. For e
|
|||||||
- Format: `www.domain.com`, `domain.com`, `sub.domain.com`, `local`, `ip`, `ip:port`
|
- Format: `www.domain.com`, `domain.com`, `sub.domain.com`, `local`, `ip`, `ip:port`
|
||||||
- Redirect: `http://{dest}`
|
- Redirect: `http://{dest}`
|
||||||
|
|
||||||
|
### Docker integration
|
||||||
|
|
||||||
|
In order to use the Docker integration, each container must have the following labels:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
labels:
|
||||||
|
- flame.type=application # "app" works too
|
||||||
|
- flame.name=My container
|
||||||
|
- flame.url=https://example.com
|
||||||
|
- flame.icon=icon-name # Optional, default is "docker"
|
||||||
|
```
|
||||||
|
|
||||||
|
And you must have activated the Docker sync option in the settings panel.
|
||||||
|
|
||||||
### Custom CSS
|
### Custom CSS
|
||||||
|
|
||||||
> This is an experimental feature. Its behaviour might change in the future.
|
> This is an experimental feature. Its behaviour might change in the future.
|
||||||
|
@ -40,7 +40,9 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
|||||||
useOrdering: 'createdAt',
|
useOrdering: 'createdAt',
|
||||||
appsSameTab: 0,
|
appsSameTab: 0,
|
||||||
bookmarksSameTab: 0,
|
bookmarksSameTab: 0,
|
||||||
searchSameTab: 0
|
searchSameTab: 0,
|
||||||
|
dockerApps:1,
|
||||||
|
unpinStoppedApps: 1
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get config
|
// Get config
|
||||||
@ -57,7 +59,9 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
|||||||
useOrdering: searchConfig('useOrdering', 'createdAt'),
|
useOrdering: searchConfig('useOrdering', 'createdAt'),
|
||||||
appsSameTab: searchConfig('appsSameTab', 0),
|
appsSameTab: searchConfig('appsSameTab', 0),
|
||||||
bookmarksSameTab: searchConfig('bookmarksSameTab', 0),
|
bookmarksSameTab: searchConfig('bookmarksSameTab', 0),
|
||||||
searchSameTab: searchConfig('searchSameTab', 0)
|
searchSameTab: searchConfig('searchSameTab', 0),
|
||||||
|
dockerApps: searchConfig('dockerApps', 1),
|
||||||
|
unpinStoppedApps: searchConfig('unpinStoppedApps', 1)
|
||||||
})
|
})
|
||||||
}, [props.loading]);
|
}, [props.loading]);
|
||||||
|
|
||||||
@ -243,6 +247,31 @@ const OtherSettings = (props: ComponentProps): JSX.Element => {
|
|||||||
<option value={0}>False</option>
|
<option value={0}>False</option>
|
||||||
</select>
|
</select>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
<h2 className={classes.SettingsSection}>Docker</h2>
|
||||||
|
<InputGroup>
|
||||||
|
<label htmlFor='dockerApps'>Use Docker API</label>
|
||||||
|
<select
|
||||||
|
id='dockerApps'
|
||||||
|
name='dockerApps'
|
||||||
|
value={formData.dockerApps}
|
||||||
|
onChange={(e) => inputChangeHandler(e, true)}
|
||||||
|
>
|
||||||
|
<option value={1}>True</option>
|
||||||
|
<option value={0}>False</option>
|
||||||
|
</select>
|
||||||
|
</InputGroup>
|
||||||
|
<InputGroup>
|
||||||
|
<label htmlFor='unpinStoppedApps'>Unpin stopped containers / other apps</label>
|
||||||
|
<select
|
||||||
|
id='unpinStoppedApps'
|
||||||
|
name='unpinStoppedApps'
|
||||||
|
value={formData.unpinStoppedApps}
|
||||||
|
onChange={(e) => inputChangeHandler(e, true)}
|
||||||
|
>
|
||||||
|
<option value={1}>True</option>
|
||||||
|
<option value={0}>False</option>
|
||||||
|
</select>
|
||||||
|
</InputGroup>
|
||||||
<Button>Save changes</Button>
|
<Button>Save changes</Button>
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
|
@ -18,4 +18,6 @@ export interface SettingsForm {
|
|||||||
appsSameTab: number;
|
appsSameTab: number;
|
||||||
bookmarksSameTab: number;
|
bookmarksSameTab: number;
|
||||||
searchSameTab: number;
|
searchSameTab: number;
|
||||||
|
dockerApps: number;
|
||||||
|
unpinStoppedApps: number;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ const ErrorResponse = require('../utils/ErrorResponse');
|
|||||||
const App = require('../models/App');
|
const App = require('../models/App');
|
||||||
const Config = require('../models/Config');
|
const Config = require('../models/Config');
|
||||||
const { Sequelize } = require('sequelize');
|
const { Sequelize } = require('sequelize');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
// @desc Create new app
|
// @desc Create new app
|
||||||
// @route POST /api/apps
|
// @route POST /api/apps
|
||||||
@ -45,10 +46,61 @@ exports.getApps = asyncWrapper(async (req, res, next) => {
|
|||||||
const useOrdering = await Config.findOne({
|
const useOrdering = await Config.findOne({
|
||||||
where: { key: 'useOrdering' }
|
where: { key: 'useOrdering' }
|
||||||
});
|
});
|
||||||
|
const useDockerApi = await Config.findOne({
|
||||||
|
where: { key: 'dockerApps' }
|
||||||
|
});
|
||||||
|
const unpinStoppedApps = await Config.findOne({
|
||||||
|
where: { key: 'unpinStoppedApps' }
|
||||||
|
});
|
||||||
|
|
||||||
const orderType = useOrdering ? useOrdering.value : 'createdAt';
|
const orderType = useOrdering ? useOrdering.value : 'createdAt';
|
||||||
let apps;
|
let apps;
|
||||||
|
|
||||||
|
|
||||||
|
if (useDockerApi && useDockerApi.value==1) {
|
||||||
|
let {data:containers} = await axios.get('http://localhost/containers/json?{"status":["running"]}', {
|
||||||
|
socketPath: '/var/run/docker.sock'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (containers) {
|
||||||
|
apps = await App.findAll({
|
||||||
|
order: [[ orderType, 'ASC' ]]
|
||||||
|
});
|
||||||
|
|
||||||
|
containers = containers.filter((e) => Object.keys(e.Labels).length !== 0);
|
||||||
|
const dockerApps = [];
|
||||||
|
for (const container of containers) {
|
||||||
|
const labels = container.Labels;
|
||||||
|
|
||||||
|
if ('flame.name' in labels && 'flame.url' in labels && (labels['flame.type']==='application' || labels['flame.type']==='app')) {
|
||||||
|
dockerApps.push({
|
||||||
|
name: labels['flame.name'],
|
||||||
|
url: labels['flame.url'],
|
||||||
|
icon: labels['flame.icon'] || 'docker'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unpinStoppedApps && unpinStoppedApps.value==1) {
|
||||||
|
for (const app of apps) {
|
||||||
|
await app.update({ isPinned: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of dockerApps) {
|
||||||
|
if (apps.some(app => app.name === item.name)) {
|
||||||
|
const app = apps.filter(e => e.name === item.name)[0];
|
||||||
|
await app.update({ ...item,isPinned: true });
|
||||||
|
} else {
|
||||||
|
await App.create({
|
||||||
|
...item,
|
||||||
|
isPinned: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (orderType == 'name') {
|
if (orderType == 'name') {
|
||||||
apps = await App.findAll({
|
apps = await App.findAll({
|
||||||
order: [[ Sequelize.fn('lower', Sequelize.col('name')), 'ASC' ]]
|
order: [[ Sequelize.fn('lower', Sequelize.col('name')), 'ASC' ]]
|
||||||
@ -59,7 +111,8 @@ exports.getApps = asyncWrapper(async (req, res, next) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({
|
// Set header to fetch containers info every time
|
||||||
|
res.status(200).setHeader('Cache-Control','no-store').json({
|
||||||
success: true,
|
success: true,
|
||||||
data: apps
|
data: apps
|
||||||
})
|
})
|
||||||
|
@ -63,6 +63,14 @@
|
|||||||
{
|
{
|
||||||
"key": "defaultSearchProvider",
|
"key": "defaultSearchProvider",
|
||||||
"value": "d"
|
"value": "d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "dockerApps",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "unpinStoppedApps",
|
||||||
|
"value": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user