{%- if model_cache_v1 %}
{%- include "cache.Dockerfile.jinja" %}
{%- endif %} {#- endif model_cache_v1 #}

{%- set requires_live_reload = config.live_reload and not config.docker_server %}

{% extends "base.Dockerfile.jinja" %}

{% block base_image_patch %}
{# If user base image is supplied in config, apply build commands from truss base image #}
{% if config.base_image %}
    {%- if not config.docker_server %}
ENV PYTHONUNBUFFERED="True"
ENV DEBIAN_FRONTEND="noninteractive"

{# Install common dependencies #}
RUN apt update && \
    apt install -y bash \
                build-essential \
                git \
                curl \
                ca-certificates \
                software-properties-common \
    && apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*

COPY ./{{ base_server_requirements_filename }} {{ base_server_requirements_filename }}
RUN {{ sys_pip_install_command }} -r {{ base_server_requirements_filename }} --no-cache-dir
    {%- endif %} {#- endif not config.docker_server #}

    {%- if requires_live_reload %}
    {# Create symlink for inference server IF a user base image is supplied and live_reload is enabled. #}
    {# This links the base images primary python executable path to /usr/local/bin/python. #}
    {# This is specific to the user-provided base image scenario. #}
RUN readlink {{ config.base_image.python_executable_path }} &>/dev/null \
    && echo "WARNING: Overwriting existing link at /usr/local/bin/python"
RUN ln -sf {{ config.base_image.python_executable_path }} /usr/local/bin/python
    {%- endif %} {#- endif requires_live_reload #}
{% endif %} {#- endif config.base_image #}

{% endblock %} {#- endblock base_image_patch #}

{% block install_requirements %}
    {%- if should_install_server_requirements %}
COPY ./{{ server_requirements_filename }} {{ server_requirements_filename }}
RUN {{ sys_pip_install_command }} -r {{ server_requirements_filename }} --no-cache-dir
    {%- endif %} {#- endif should_install_server_requirements #}
{{ super() }}
{% endblock %} {#- endblock install_requirements #}


{% block app_copy %}
{%- if model_cache_v1 %}
# Copy data before code for better caching
{%- include "copy_cache_files.Dockerfile.jinja" -%}
{%- endif %} {#- endif model_cache_v1 #}

{%- if external_data_files %}
{% for url, dst in external_data_files %}
RUN mkdir -p {{ dst.parent }}; curl -L "{{ url }}" -o {{ dst }}
{% endfor %} {#- endfor external_data_files #}
{%- endif %} {#- endif external_data_files #}

{%- if build_commands %}
{% for command in build_commands %}
RUN {% for secret,path in config.build.secret_to_path_mapping.items() %} --mount=type=secret,id={{ secret }},target={{ path }}{%- endfor %} {{ command }}
{% endfor %} {#- endfor build_commands #}
{%- endif %} {#- endif build_commands #}

{# Copy data before code for better caching #}
{%- if data_dir_exists %}
COPY ./{{ config.data_dir }} /app/data
{%- endif %} {#- endif data_dir_exists #}

{%- if model_cache_v2 %}
# v0.0.9, keep synced with server_requirements.txt
RUN curl -sSL --fail --retry 5 --retry-delay 2 -o /usr/local/bin/truss-transfer-cli https://github.com/basetenlabs/truss/releases/download/v0.9.121rc5/truss-transfer-cli-v0.9.121rc5-linux-x86_64-unknown-linux-musl
RUN chmod +x /usr/local/bin/truss-transfer-cli
RUN mkdir /static-bptr
RUN echo "hash {{model_cache_hash}}"
COPY ./bptr-manifest /static-bptr/static-bptr-manifest.json
{%- endif %} {#- endif model_cache_v2 #}

{%- if not config.docker_server %}
COPY ./server /app
{%- endif %} {#- endif not config.docker_server #}

{%- if use_local_src %}
{# This path takes precedence over site-packages. #}
COPY ./truss_chains /app/truss_chains
COPY ./truss /app/truss
{%- endif %} {#- endif use_local_src #}

COPY ./config.yaml /app/config.yaml
{%- if requires_live_reload %}
RUN uv python install {{ control_python_version }}
RUN uv venv /control/.env --python {{ control_python_version }}

COPY ./control /control
RUN uv pip install -r /control/requirements.txt --python /control/.env/bin/python --no-cache-dir
{%- endif %} {#- endif requires_live_reload #}

{%- if model_dir_exists %}
COPY ./{{ config.model_module_dir }} /app/model
{%- endif %} {#- endif model_dir_exists #}
{% endblock %} {#- endblock app_copy #}

{% block run %}
    {%- if config.docker_server %}
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        curl nginx && rm -rf /var/lib/apt/lists/*
COPY ./docker_server_requirements.txt /app/docker_server_requirements.txt

{# NB(nikhil): Use the same python version for custom server proxy as the control server, for consistency. #}
RUN uv python install {{ control_python_version }}
RUN uv venv /docker_server/.venv --python {{ control_python_version }}
RUN uv pip install --python /docker_server/.venv/bin/python -r /app/docker_server_requirements.txt --no-cache-dir
{% set proxy_config_path = "/etc/nginx/conf.d/proxy.conf" %}
{% set supervisor_config_path = "/etc/supervisor/supervisord.conf" %}
{% set supervisor_log_dir = "/var/log/supervisor" %}
{% set supervisor_server_url = "http://localhost:8080" %}
COPY ./proxy.conf {{ proxy_config_path }}
RUN mkdir -p {{ supervisor_log_dir }}
COPY supervisord.conf {{ supervisor_config_path }}
ENV SUPERVISOR_SERVER_URL="{{ supervisor_server_url }}"
ENV SERVER_START_CMD="/docker_server/.venv/bin/supervisord -c {{ supervisor_config_path }}"
ENTRYPOINT ["/docker_server/.venv/bin/supervisord", "-c", "{{ supervisor_config_path }}"]
    {%- elif requires_live_reload %} {#- elif requires_live_reload #}
ENV HASH_TRUSS="{{ truss_hash }}"
ENV CONTROL_SERVER_PORT="8080"
ENV INFERENCE_SERVER_PORT="8090"
ENV SERVER_START_CMD="/control/.env/bin/python /control/control/server.py"
ENTRYPOINT ["/control/.env/bin/python", "/control/control/server.py"]
    {%- else %} {#- else (default inference server) #}
ENV INFERENCE_SERVER_PORT="8080"
ENV SERVER_START_CMD="{{ python_executable }} /app/main.py"
ENTRYPOINT ["{{ python_executable }}", "/app/main.py"]
    {%- endif %} {#- endif config.docker_server / live_reload #}
{% endblock %} {#- endblock run #}
