Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This mod gives SWAG the ability to start containers on-demand when accessed thro
access_log /config/log/nginx/access.log main;
```
- *Optional* - Additional environment variables
- `SWAG_ONDEMAND_STOP_THRESHOLD` - duration of inactivity in seconds before stopping on-demand containers, defaults to `600` (10 minutes).
- `SWAG_ONDEMAND_STOP_THRESHOLD` - duration of inactivity in seconds before stopping on-demand containers, defaults to `600` (10 minutes). Can be overridden per container with the `swag_ondemand_stop_threshold` label.
- `SWAG_ONDEMAND_CONTAINER_QUERY_SLEEP` - sleep time in seconds between querying containers, defaults to `5.0`.
- `SWAG_ONDEMAND_LOG_READER_SLEEP` - sleep time in seconds between log reads, defaults to `1.0`.
- `SWAG_ONDEMAND_DOCKER_API_TIMEOUT` - the timeout for docker's API. Defaults to `5`.
Expand Down Expand Up @@ -81,12 +81,14 @@ Or set the following label if using `swag-auto-proxy`:
- `swag_ondemand=enable` - required for on-demand.
- `swag_ondemand_urls=https://wake.domain.com,https://app.domain.com/up` - *optional* - overrides the monitored URLs for starting the container on-demand. Defaults to using the value of the `swag_url` label, if you've already set it for `swag-auto-proxy`, or `https://somecontainer.,http://somecontainer.` otherwise.
- `swag_ondemand_websocket=1` - required for apps that communicate over a websocket, such as selkies based apps.
- `swag_ondemand_stop_threshold=300` - *optional* - overrides `SWAG_ONDEMAND_STOP_THRESHOLD` for this container. Must be a positive whole number of seconds, otherwise `SWAG_ONDEMAND_STOP_THRESHOLD` is used.

### URLs:
- Accessed URLs need to start with one of `swag_ondemand_urls` to be matched, for example, setting `swag_ondemand_urls=https://plex.` will apply to `https://plex.domain.com` and `https://plex.domain.com/something`.
- `swag_ondemand_urls` default to `https://somecontainer.,http://somecontainer.`, for example `https://plex.,http://plex.`.
- `swag_ondemand_urls` don't need to be valid, it will work as long as it reaches swag and gets logged by nginx under `/config/log/nginx/access.log`.
- The same URL can be set on multiple containers and all of them will be started when accessing that URL.
- Containers sharing a URL are stopped independently, each according to its own stop threshold.

### Logging:
The log file can be found under `/config/log/ondemand/ondemand.log`.
Expand Down
18 changes: 14 additions & 4 deletions root/app/ondemand/container_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,31 @@ def process_containers(self):
default_url = container.labels.get("swag_url", f"{container.name}.").rstrip("*")
container_urls = container.labels.get("swag_ondemand_urls", f"https://{default_url},http://{default_url}")
websocket = container.labels.get("swag_ondemand_websocket", "0").lower() in ("true", "1")
try:
stop_threshold = int(container.labels.get("swag_ondemand_stop_threshold", STOP_THRESHOLD))
except ValueError:
stop_threshold = STOP_THRESHOLD
if stop_threshold <= 0:
stop_threshold = STOP_THRESHOLD

if container.name in docker_host.ondemand_containers:
docker_host.ondemand_containers[container.name].status = container.status
docker_host.ondemand_containers[container.name].websocket = websocket
if container_urls != docker_host.ondemand_containers[container.name].urls:
docker_host.ondemand_containers[container.name].urls = container_urls
logging.info(f"Updated urls for {container.name} on {docker_host.url} to: {container_urls}")
if stop_threshold != docker_host.ondemand_containers[container.name].stop_threshold:
docker_host.ondemand_containers[container.name].stop_threshold = stop_threshold
logging.info(f"Updated stop threshold for {container.name} on {docker_host.url} to: {stop_threshold}s")
else:
docker_host.ondemand_containers[container.name] = OnDemandContainer(
status=container.status,
urls=container_urls,
last_accessed=datetime.now(),
websocket=websocket
websocket=websocket,
stop_threshold=stop_threshold
)
logging.info(f"Started monitoring {container.name} on {docker_host.url} for urls: {container_urls}")
logging.info(f"Started monitoring {container.name} on {docker_host.url} for urls: {container_urls}, stop threshold: {stop_threshold}s")


def stop_containers(self, websocket_terminated_urls_combined: str):
Expand All @@ -97,7 +107,7 @@ def stop_containers(self, websocket_terminated_urls_combined: str):
continue

inactive_seconds = (datetime.now() - ondemand_container.last_accessed).total_seconds()
if inactive_seconds < STOP_THRESHOLD:
if inactive_seconds < ondemand_container.stop_threshold:
continue

container = docker_host.get_container(container_name)
Expand All @@ -106,7 +116,7 @@ def stop_containers(self, websocket_terminated_urls_combined: str):

container.stop()
ondemand_container.status = "exited"
logging.info(f"Stopped {container_name} on {docker_host.url} after {STOP_THRESHOLD}s of inactivity")
logging.info(f"Stopped {container_name} on {docker_host.url} after {ondemand_container.stop_threshold}s of inactivity")

def start_containers(self, last_accessed_urls_combined: str):
if not last_accessed_urls_combined:
Expand Down
1 change: 1 addition & 0 deletions root/app/ondemand/data_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class OnDemandContainer:
urls: str
last_accessed: datetime
websocket: bool
stop_threshold: int
terminated: bool = False

@dataclass
Expand Down
Loading