FROM python:3.11-alpine # Enforcement to ensure passwords environment variables are not left blank. # This won't stop bad passwords from being used, but at least won't cause # errors or, worse, weaker crypt. ARG POSTGRES_PASSWORD ENV ENV_POSTGRES_PASSWORD=${POSTGRES_PASSWORD} ARG GHOSTFORGE_JWT_SECRET ENV ENV_GHOSTFORGE_JWT_SECRET=${GHOSTFORGE_JWT_SECRET} RUN [ ! -z "${ENV_POSTGRES_PASSWORD}" ] || { echo "ghostforge build error: Set POSTGRES_PASSWORD in .env."; exit 1; } RUN [ ! -z "${ENV_GHOSTFORGE_JWT_SECRET}" ] || { echo "ghostforge build error: Set GHOSTFORGE_JWT_SECRET in .env."; exit 1; } # Create the data directory specified using the environment variables. # This is redundant for mapped volumes, but necessary if the data # directory is specified but not mapped. ARG GHOSTFORGE_DATA_DIR ENV ENV_GHOSTFORGE_DATA_DIR=${GHOSTFORGE_DATA_DIR} RUN mkdir -p "${ENV_GHOSTFORGE_DATA_DIR}" # Copy project into Docker image, skipping entries in .dockerignore. WORKDIR /ghostforge COPY . . # Install cffi dependencies for pip install. RUN apk add --update --no-cache --virtual ghostforge_build libffi-dev musl-dev gcc # Install ghostforge from the work directory. RUN pip install . # Remove cffi dependencies for space. RUN apk del ghostforge_build # Expose the web "serve" port specific in the environment variables. ARG GHOSTFORGE_INTERNAL_WEB_PORT ENV ENV_GHOSTFORGE_INTERNAL_WEB_PORT=${GHOSTFORGE_INTERNAL_WEB_PORT} EXPOSE ${ENV_GHOSTFORGE_INTERNAL_WEB_PORT} ENV PYTHONPATH=/ghostforge # TODO: Replace with ghostforge_serve when it works. # This currently just keeps the container running for development. CMD ["sh", "-c", "alembic upgrade head && uvicorn ghostforge.serve:gf --host 0.0.0.0 --port $GHOSTFORGE_INTERNAL_WEB_PORT"]