deploymate / app /services /docker_generator.py
shakauthossain's picture
V2.0.0
2df0cf9 verified
"""
Docker file generation service.
"""
from typing import Union
from pathlib import Path
from fastapi import HTTPException, status
from jinja2 import Environment, Template
from app.core.config import Settings
from app.models.schemas import DockerfileConfig, DockerComposeConfig
class DockerGenerator:
"""Service for generating Docker files and configurations."""
def __init__(self, template_env: Environment, settings: Settings, logger):
self.template_env = template_env
self.settings = settings
self.logger = logger
def generate_dockerfile(self, config: DockerfileConfig, file_id: str) -> str:
"""
Generate a Dockerfile based on stack type and configuration.
"""
stack = config.stackType.lower()
# Map stack to template
template_map = {
"nodejs": "docker/dockerfile_nodejs.j2",
"python": "docker/dockerfile_python.j2",
"php": "docker/dockerfile_php.j2",
"go": "docker/dockerfile_go.j2",
"java": "docker/dockerfile_java.j2",
"dotnet": "docker/dockerfile_dotnet.j2",
"ruby": "docker/dockerfile_ruby.j2",
}
template_name = template_map.get(stack)
if not template_name:
raise ValueError(f"Unsupported stack type: {stack}")
try:
# Read template from disk
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
dockerfile_content = template.render(config=config, file_id=file_id)
return dockerfile_content
except Exception as e:
self.logger.error(f"Failed to generate Dockerfile: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate Dockerfile: {str(e)}"
)
def generate_docker_compose(self, config: DockerComposeConfig, file_id: str) -> str:
"""
Generate a docker-compose.yml based on configuration.
"""
template_name = "docker/docker-compose.yml.j2"
try:
# Read template from disk
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
compose_content = template.render(config=config, file_id=file_id)
return compose_content
except Exception as e:
self.logger.error(f"Failed to generate docker-compose: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate docker-compose: {str(e)}"
)
def generate_dockerignore(self, config: Union[DockerfileConfig, DockerComposeConfig], file_id: str) -> str:
"""
Generate a .dockerignore file.
"""
template_name = "docker/dockerignore.j2"
try:
# Read template from disk
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
dockerignore_content = template.render(config=config, file_id=file_id)
return dockerignore_content
except Exception as e:
self.logger.error(f"Failed to generate .dockerignore: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate .dockerignore: {str(e)}"
)
def generate_env_example(self, config: DockerComposeConfig, file_id: str) -> str:
"""
Generate a .env.example file for docker-compose.
"""
template_name = "docker/env.example.j2"
try:
# Read template from disk
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
env_content = template.render(config=config, file_id=file_id)
return env_content
except Exception as e:
self.logger.error(f"Failed to generate .env.example: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate .env.example: {str(e)}"
)
def generate_build_script(self, config: DockerComposeConfig, file_id: str) -> str:
"""
Generate a docker-build.sh helper script.
"""
template_name = "docker/docker-build.sh.j2"
try:
# Read template from disk
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
script_content = template.render(config=config, file_id=file_id)
return script_content
except Exception as e:
self.logger.error(f"Failed to generate build script: {str(e)}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate build script: {str(e)}"
)