mirror of
https://github.com/nextcloud/all-in-one.git
synced 2025-09-12 01:24:45 +08:00
feat: Add shared_secrets and shared_environment for community containers
- Add shared_secrets property to allow community containers to share secrets via placeholders - Add shared_environment property to share environment variables across all AIO containers - Update containers-schema.json with new properties grouped logically - Extend Container class with sharedSecrets and sharedEnvironment support - Update ContainerDefinitionFetcher to parse new properties - Implement getAllSharedEnvironmentVariables() in DockerActionManager - Add comprehensive documentation in community-containers/readme.md - Update facerecognition.json as reference implementation Enables community containers to securely share secrets and configuration with Nextcloud and other containers while maintaining explicit control over what gets shared. Signed-off-by: Benjamin Brahmer <info@b-brahmer.de>
This commit is contained in:
parent
ca0e7980b3
commit
b79d339449
6 changed files with 134 additions and 6 deletions
|
@ -10,18 +10,21 @@
|
|||
"restart": "unless-stopped",
|
||||
"environment": [
|
||||
"TZ=%TIMEZONE%",
|
||||
"API_KEY=some-super-secret-api-key",
|
||||
"API_KEY=%FACERECOGNITION_API_KEY%",
|
||||
"FACE_MODEL=3"
|
||||
],
|
||||
"aio_variables": [
|
||||
"nextcloud_memory_limit=2048M"
|
||||
],
|
||||
"shared_secrets": [
|
||||
"FACERECOGNITION_API_KEY"
|
||||
],
|
||||
"enable_nvidia_gpu": false,
|
||||
"nextcloud_exec_commands": [
|
||||
"php /var/www/html/occ app:install facerecognition",
|
||||
"php /var/www/html/occ app:enable facerecognition",
|
||||
"php /var/www/html/occ config:system:set facerecognition.external_model_url --value nextcloud-aio-facerecognition:5000",
|
||||
"php /var/www/html/occ config:system:set facerecognition.external_model_api_key --value some-super-secret-api-key",
|
||||
"php /var/www/html/occ config:system:set facerecognition.external_model_api_key --value %FACERECOGNITION_API_KEY%",
|
||||
"php /var/www/html/occ face:setup -m 5",
|
||||
"php /var/www/html/occ face:setup -M 1G",
|
||||
"php /var/www/html/occ config:app:set facerecognition analysis_image_area --value 4320000",
|
||||
|
|
|
@ -11,6 +11,54 @@ Starting with v11 of AIO, the management of Community Containers is done via the
|
|||
## How to add containers?
|
||||
Simply submit a PR by creating a new folder in this directory: https://github.com/nextcloud/all-in-one/tree/main/community-containers with the name of your container. It must include a json file with the same name and with correct syntax and a readme.md with additional information. You might get inspired by caddy, fail2ban, local-ai, libretranslate, plex, pi-hole or vaultwarden (subfolders in this directory). For a full-blown example of the json file, see https://github.com/nextcloud/all-in-one/blob/main/php/containers.json. The json-schema that it validates against can be found here: https://github.com/nextcloud/all-in-one/blob/main/php/containers-schema.json.
|
||||
|
||||
## Sharing Secrets and Environment Variables with Other Containers
|
||||
|
||||
Community containers can share secrets and environment variables with all other AIO containers (including Nextcloud) using `shared_secrets` and `shared_environment`.
|
||||
|
||||
### shared_secrets
|
||||
Secrets that can be accessed via placeholder replacement (like `%SECRET_NAME%`) in:
|
||||
- Your container's `environment` variables
|
||||
- Your container's `nextcloud_exec_commands`
|
||||
- Other containers that also define the same secret name
|
||||
|
||||
Same like with `secrets` a random secure key is generated and provided via that variable.
|
||||
|
||||
```json
|
||||
{
|
||||
"shared_secrets": ["MY_API_KEY"]
|
||||
}
|
||||
```
|
||||
|
||||
### shared_environment
|
||||
Environment variables that are automatically added to **ALL** AIO containers. Uses the same format as regular `environment` but gets shared globally.
|
||||
|
||||
```json
|
||||
{
|
||||
"shared_environment": [
|
||||
"MY_API_KEY=%MY_API_KEY%",
|
||||
"SERVICE_URL=http://nextcloud-aio-myservice:5000",
|
||||
"FEATURE_ENABLED=yes"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Important Considerations
|
||||
|
||||
⚠️ **Name Conflicts**: If multiple community containers use the same environment variable name in `shared_environment`, the last processed container wins. Use unique prefixes (e.g., `MYSERVICE_API_KEY` instead of `API_KEY`).
|
||||
|
||||
⚠️ **Security**: Only share what's necessary. `shared_environment` variables are visible in ALL containers, so avoid sharing sensitive data unless required.
|
||||
|
||||
⚠️ **Dependencies**: If your service URL or configuration is shared via `shared_environment`, other containers might depend on your container being enabled. Document this clearly.
|
||||
|
||||
⚠️ **Testing**: Test your container both standalone and with other community containers enabled to ensure no conflicts.
|
||||
|
||||
### Best Practices
|
||||
|
||||
✅ **Use descriptive, unique names**: `MYSERVICE_API_KEY` instead of `API_KEY`
|
||||
✅ **Document shared variables**: Clearly explain what your container shares in your readme.md
|
||||
✅ **Minimal sharing**: Only use `shared_environment` when other containers need access
|
||||
✅ **Prefix service URLs**: Use your container name in shared URLs (e.g., `MYSERVICE_URL`)
|
||||
|
||||
### Is there a list of ideas for new community containers?
|
||||
Yes, see [this list](https://github.com/nextcloud/all-in-one/issues/5251) for already existing ideas for new community containers. Feel free to pick one up and add it to this folder by following the instructions above.
|
||||
|
||||
|
@ -18,3 +66,4 @@ Yes, see [this list](https://github.com/nextcloud/all-in-one/issues/5251) for al
|
|||
You can remove containers now via the web interface.
|
||||
|
||||
After removing the containers, there might be some data left on your server that you might want to remove. You can get rid of the data by first running `sudo docker rm nextcloud-aio-container1`, (adjust `container1` accordingly) per community-container that you removed. Then run `sudo docker image prune -a` in order to remove all images that are not used anymore. As last step you can get rid of persistent data of these containers that is stored in volumes. You can check if there is some by running `sudo docker volume ls` and look for any volume that matches the ones that you removed. If so, you can remove them with `sudo docker volume rm nextcloud_aio_volume-id` (of course you need to adjust the `volume-id`). **Please note:** If you do not have CLI access to the server, you can now run docker commands via a web session by using this community container: https://github.com/nextcloud/all-in-one/tree/main/community-containers/container-management
|
||||
|
||||
|
|
|
@ -57,6 +57,14 @@
|
|||
"minlength": 1
|
||||
}
|
||||
},
|
||||
"shared_environment": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^.*=.*$",
|
||||
"minlength": 1
|
||||
}
|
||||
},
|
||||
"container_name": {
|
||||
"type": "string",
|
||||
"pattern": "^nextcloud-aio-[a-z0-9-]+$"
|
||||
|
@ -145,6 +153,13 @@
|
|||
"pattern": "^[A-Z_]+$"
|
||||
}
|
||||
},
|
||||
"shared_secrets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_]+$"
|
||||
}
|
||||
},
|
||||
"ui_secret": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z_]+$"
|
||||
|
|
|
@ -17,10 +17,14 @@ readonly class Container {
|
|||
private string $internalPorts,
|
||||
private ContainerVolumes $volumes,
|
||||
private ContainerEnvironmentVariables $containerEnvironmentVariables,
|
||||
/** @var array */
|
||||
private array $sharedEnvironment,
|
||||
/** @var string[] */
|
||||
private array $dependsOn,
|
||||
/** @var string[] */
|
||||
private array $secrets,
|
||||
/** @var string[] */
|
||||
private array $sharedSecrets,
|
||||
private string $uiSecret,
|
||||
/** @var string[] */
|
||||
private array $devices,
|
||||
|
@ -82,10 +86,22 @@ readonly class Container {
|
|||
return $this->maxShutdownTime;
|
||||
}
|
||||
|
||||
public function GetEnvironmentVariables() : ContainerEnvironmentVariables {
|
||||
return $this->containerEnvironmentVariables;
|
||||
}
|
||||
|
||||
public function GetSharedEnvironment() : array {
|
||||
return $this->sharedEnvironment;
|
||||
}
|
||||
|
||||
public function GetSecrets() : array {
|
||||
return $this->secrets;
|
||||
}
|
||||
|
||||
public function GetSharedSecrets() : array {
|
||||
return $this->sharedSecrets;
|
||||
}
|
||||
|
||||
public function GetUiSecret() : string {
|
||||
return $this->dockerActionManager->GetAndGenerateSecretWrapper($this->uiSecret);
|
||||
}
|
||||
|
@ -149,10 +165,6 @@ readonly class Container {
|
|||
return $this->nextcloudExecCommands;
|
||||
}
|
||||
|
||||
public function GetEnvironmentVariables() : ContainerEnvironmentVariables {
|
||||
return $this->containerEnvironmentVariables;
|
||||
}
|
||||
|
||||
public function GetAioVariables() : AioVariables {
|
||||
return $this->aioVariables;
|
||||
}
|
||||
|
|
|
@ -239,11 +239,21 @@ readonly class ContainerDefinitionFetcher {
|
|||
$internalPort = $entry['internal_port'];
|
||||
}
|
||||
|
||||
$sharedEnvironment = [];
|
||||
if (isset($entry['shared_environment'])) {
|
||||
$sharedEnvironment = $entry['shared_environment'];
|
||||
}
|
||||
|
||||
$secrets = [];
|
||||
if (isset($entry['secrets'])) {
|
||||
$secrets = $entry['secrets'];
|
||||
}
|
||||
|
||||
$sharedSecrets = [];
|
||||
if (isset($entry['shared_secrets'])) {
|
||||
$sharedSecrets = $entry['shared_secrets'];
|
||||
}
|
||||
|
||||
$uiSecret = '';
|
||||
if (isset($entry['ui_secret'])) {
|
||||
$uiSecret = $entry['ui_secret'];
|
||||
|
@ -319,8 +329,10 @@ readonly class ContainerDefinitionFetcher {
|
|||
$internalPort,
|
||||
$volumes,
|
||||
$variables,
|
||||
$sharedEnvironment,
|
||||
$dependsOn,
|
||||
$secrets,
|
||||
$sharedSecrets,
|
||||
$uiSecret,
|
||||
$devices,
|
||||
$enableNvidiaGpu,
|
||||
|
|
|
@ -225,6 +225,11 @@ readonly class DockerActionManager {
|
|||
$this->configurationManager->GetAndGenerateSecret($secret);
|
||||
}
|
||||
|
||||
// Generate shared secrets for this container
|
||||
foreach ($container->GetSharedSecrets() as $sharedSecret) {
|
||||
$this->configurationManager->GetAndGenerateSecret($sharedSecret);
|
||||
}
|
||||
|
||||
$aioVariables = $container->GetAioVariables()->GetVariables();
|
||||
foreach ($aioVariables as $variable) {
|
||||
$config = $this->configurationManager->GetConfig();
|
||||
|
@ -239,6 +244,13 @@ readonly class DockerActionManager {
|
|||
if ($container->GetIdentifier() === 'nextcloud-aio-nextcloud') {
|
||||
$envs[] = $this->GetAllNextcloudExecCommands();
|
||||
}
|
||||
|
||||
// Add shared environment variables from community containers to all containers
|
||||
$sharedEnvironmentVars = $this->getAllSharedEnvironmentVariables();
|
||||
foreach ($sharedEnvironmentVars as $envVar) {
|
||||
$envs[] = $envVar;
|
||||
}
|
||||
|
||||
foreach ($envs as $key => $env) {
|
||||
$envs[$key] = $this->replaceEnvPlaceholders($env);
|
||||
}
|
||||
|
@ -1024,4 +1036,29 @@ readonly class DockerActionManager {
|
|||
return $this->dockerHubManager->GetLatestDigestOfTag($imageName, $tag);
|
||||
}
|
||||
}
|
||||
|
||||
private function getAllSharedEnvironmentVariables(): array {
|
||||
$sharedEnvironmentVars = [];
|
||||
|
||||
// Get all enabled community containers
|
||||
$enabledCommunityContainers = $this->configurationManager->GetEnabledCommunityContainers();
|
||||
|
||||
foreach ($enabledCommunityContainers as $communityContainer) {
|
||||
if ($communityContainer !== '') {
|
||||
try {
|
||||
$container = $this->containerDefinitionFetcher->GetContainerById('nextcloud-aio-' . $communityContainer);
|
||||
|
||||
// Process shared_environment variables (same format as regular environment)
|
||||
foreach ($container->GetSharedEnvironment() as $envVar) {
|
||||
$sharedEnvironmentVars[] = $envVar;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Container might not exist or have issues, continue with others
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sharedEnvironmentVars;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue