# This Dockerfile is for deployment on Google Cloud Run. It requires a few setup
# steps to work, including creating the right GCP resources and setting the
# correct environment variables during deployment.

# Use Python 3.10 + Debian
FROM python:3.10-slim-bookworm AS main-image

# Install deps:
# - git, which we need for local builds with Docker (it is used to delete all
#   the .gitignored files introduced by COPY).
# - pgbouncer, which is used to reduce the number of connections made to our
#   postgres instance.
# - postgres-client-15, which lets us connect directly to postgres when running
#   the image on a Compute Engine VM.
RUN export DEBIAN_FRONTEND=noninteractive \
    && apt-get update \
    && apt-get upgrade -y \
    && apt-get install --no-install-recommends -y git pgbouncer postgresql-client-15 procps \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Create a new user and switch to it
RUN useradd -ms /bin/bash promptgame

# Copy all source into the `promptgame` user's home directory
COPY . /home/promptgame/promptgame
WORKDIR /home/promptgame/promptgame
# This command cleans out anything not tracked by git, to avoid polluting the
# image with build artifacts. It also ensures that files are owned by the
# 'promptgame' user.
RUN if [ -e .git ]; then \
    git config --global --add safe.directory $(pwd) \
    && git clean -fdx \
    && git status > git_status.txt \
    && rm -r .git || exit 1; \
fi; chown promptgame:promptgame . -R || exit 1
# Execute everything from here on as `promptgame
USER promptgame
# Add ~/.local/bin to PATH
ENV PATH=/home/promptgame/.local/bin:$PATH
# Install via setup.py
RUN pip --no-cache-dir install -e ".[deploy]"
# Set up Django & run tiktoken. This has two effects:
# 1. Ensures sure that Django can find our settings and the package can be
#    imported.
# 2. Primes the tiktoken cache so we don't have to download the tokenizer data
#    the first time that promptgame.gameui.utils is run.
ENV DJANGO_SETTINGS_MODULE=promptgame.settings.docker
ENV TIKTOKEN_CACHE_DIR=/home/promptgame/.cache/tiktoken
RUN python -c "import django; django.setup(); from promptgame.gameui.utils import get_number_tokens; get_number_tokens('test', 42)"

# Build Tailwind styles. Note that this installs node.js in the same command and
# then immediately uninstalls it, because node.js pushes up the size of the
# image by several hundred MB. Weirdly, the default node install (without
# --no-install-recommends) pulls in all of X11!
USER root
RUN export DEBIAN_FRONTEND=noninteractive \
    && apt-get update \
    && apt-get install --no-install-recommends -y nodejs npm \
    && rm -rf /var/lib/apt/lists/* \
    && su promptgame -c "cd ~/promptgame \
    && ./manage.py tailwind install \
    && ./manage.py tailwind build \
    && rm -r ./src/promptgame/theme/static_src/node_modules ~/.npm" \
    && apt-get purge -y nodejs npm \
    && apt-get autoremove -y \
    && apt-get clean
USER promptgame

# Collect staticfiles so we bake the manifest into the Docker image.
# (We don't actaully need to keep the collected files.)
RUN ./manage.py collectstatic --noinput \
    && rm -r src/promptgame/collected-static

# Helper binaries for Cloud Run (e.g. collect-and-migrate, serve,
# createsuperuser)
RUN cp ./deploy/scripts/* ~/.local/bin
ENV DJANGO_SETTINGS_MODULE=promptgame.settings.cloud_run
# PYTHONUNBUFFERED is set to ensure that logs are written to stdout/stderr
ENV PYTHONUNBUFFERED=1

# Default serving command for Cloud Run (it just starts some web server tasks;
# see circus.ini for details)
CMD serve
