Source code for betty.extension.nginx.docker

"""
Integrate Betty with Docker.
"""

import asyncio
from pathlib import Path
from types import TracebackType

import docker
from docker.models.containers import Container as DockerContainer


[docs] class Container: _IMAGE_TAG = "betty-serve" def __init__( self, www_directory_path: Path, docker_directory_path: Path, nginx_configuration_file_path: Path, ): self._docker_directory_path = docker_directory_path self._nginx_configuration_file_path = nginx_configuration_file_path self._www_directory_path = www_directory_path self._client = docker.from_env() self.__container: DockerContainer | None = None async def __aenter__(self) -> None: await self.start() async def __aexit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, ) -> None: await self.stop()
[docs] async def start(self) -> None: await asyncio.to_thread(self._start)
def _start(self) -> None: self._client.images.build( path=str(self._docker_directory_path), tag=self._IMAGE_TAG ) self._container.start() self._container.exec_run(["nginx", "-s", "reload"])
[docs] async def stop(self) -> None: await asyncio.to_thread(self._stop)
def _stop(self) -> None: if self._container is not None: self._container.stop() @property def _container(self) -> DockerContainer: if self.__container is None: self.__container = self._client.containers.create( self._IMAGE_TAG, auto_remove=True, detach=True, volumes={ self._nginx_configuration_file_path: { "bind": "/etc/nginx/conf.d/betty.conf", "mode": "ro", }, self._www_directory_path: { "bind": "/var/www/betty", "mode": "ro", }, }, ) return self.__container @property def ip(self) -> DockerContainer: return self._client.api.inspect_container(self._container.id)[ "NetworkSettings" ]["Networks"]["bridge"]["IPAddress"]