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']