dockergoogle-cloud-platformgoogle-container-registrygoogle-artifact-registry

Different behavior on Google Container Registry vs Google Artifact Registry (breaking change)


I am attempting to run Dbt in Google Cloud Run with the following Dockerfile

FROM python:3.11
RUN apt-get update -y
COPY requirements.txt /
RUN pip install -r /requirements.txt
COPY . /app
WORKDIR /app
RUN chmod +x /app/entrypoint.sh
ENTRYPOINT ["/app/entrypoint.sh"]

where /app/entrypoint.sh contains

#!/bin/sh

# Check the command passed as an argument
if [ "$1" = "run" ]; then
    cd data_models && dbt run
elif [ "$1" = "test" ]; then
    cd data_models && dbt test
else
    echo "Unknown command: $1"
    exit 1
fi

With /app/entrypoint.sh as the entry point, I can successfully run run and test on my local Docker using

docker run \
-v $GOOGLE_APPLICATION_CREDENTIALS:/tmp/keys/new-life-400922-cd595a9f5804.json:ro \
-e GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/new-life-400922-cd595a9f5804.json \
arapbi run

Likewise, when I submit this to GCR with gcloud builds submit --tag gcr.io/new-life-400922/arapbi_data_models, I can create and run the job successfully using

gcloud run jobs create \
--image gcr.io/new-life-400922/arapbi_data_models:latest \
--set-secrets /secrets/dbt_credentials=dbt_credentials:latest \
--set-env-vars=GOOGLE_APPLICATION_CREDENTIALS=/secrets/dbt_credentials \
--task-timeout=15m \
--service-account=admin-509@new-life-400922.iam.gserviceaccount.com \
--args run

The problem is, when I try to move this exact same image to Artifact Registry, it no longer works. In particular, I get the following error message when I run the job:

terminated: Application failed to start: "/usr/local/bin/python": exec format error

I'm confused why the exact same image would work on GCR but not on Artifact Registry. Moreover, I'm confused why the Artifact Registry container cannot invoke Dbt, when it was successfully installed via pip as part of my requirements.txt.

If it matters, I took the following steps to push my image to Artifact Registry.

docker build . arapbi
docker tag arapbi us-west1-docker.pkg.dev/new-life-400922/arapbi/arapbi:latest
docker push us-west1-docker.pkg.dev/new-life-400922/arapbi/arapbi

As mentioned above, this job works on my local machine using the docker run invocation. But this fails once I push the image to Artifact Registry, and I'm very confused why that would be the case.

Has anyone encountered a problem like this before and/or have any ideas what might be going wrong? I've been trying to debug this for hours and I'm not getting anywhere.

Since I was asked to include my requirements file in the comments as well, here it is:

agate==1.7.1
aiohttp==3.8.6
aiosignal==1.3.1
appnope==0.1.3
asttokens==2.4.0
async-timeout==4.0.3
attrs==23.1.0
Babel==2.13.0
backcall==0.2.0
beautifulsoup4==4.12.2
cachetools==5.3.1
certifi==2023.7.22
cffi==1.16.0
cftime==1.6.2
charset-normalizer==3.3.0
click==8.1.7
colorama==0.4.6
contourpy==1.1.1
cycler==0.12.1
db-dtypes==1.1.1
dbt-bigquery==1.6.7
dbt-core==1.6.6
dbt-extractor==0.4.1
dbt-semantic-interfaces==0.2.2
decorator==5.1.1
executing==2.0.0
fonttools==4.43.1
frozenlist==1.4.0
fsspec==2023.9.2
gcsfs==2023.9.2
google-api-core==2.12.0
google-api-python-client==2.103.0
google-auth==2.23.3
google-auth-httplib2==0.1.1
google-auth-oauthlib==1.1.0
google-cloud==0.34.0
google-cloud-appengine-logging==1.3.2
google-cloud-audit-log==0.2.5
google-cloud-bigquery==3.12.0
google-cloud-bigquery-storage==2.22.0
google-cloud-core==2.3.3
google-cloud-dataproc==5.6.0
google-cloud-logging==3.8.0
google-cloud-secret-manager==2.16.4
google-cloud-storage==2.11.0
google-crc32c==1.5.0
google-resumable-media==2.6.0
googleapis-common-protos==1.60.0
grpc-google-iam-v1==0.12.6
grpcio==1.59.0
grpcio-status==1.59.0
h5py==3.10.0
hologram==0.0.16
httplib2==0.22.0
idna==3.4
importlib-metadata==6.8.0
ipython==8.16.1
isodate==0.6.1
jedi==0.19.1
Jinja2==3.1.2
jsonschema==4.19.1
jsonschema-specifications==2023.7.1
kiwisolver==1.4.5
leather==0.3.4
Logbook==1.5.3
MarkupSafe==2.1.3
mashumaro==3.8.1
matplotlib==3.8.0
matplotlib-inline==0.1.6
minimal-snowplow-tracker==0.0.2
more-itertools==8.14.0
msgpack==1.0.7
multidict==6.0.4
networkx==3.1
numpy==1.26.0
oauthlib==3.2.2
packaging==23.2
pandas==2.1.1
pandas-gbq==0.19.2
parsedatetime==2.6
parso==0.8.3
pathspec==0.11.2
pexpect==4.8.0
pickleshare==0.7.5
Pillow==10.0.1
polygon-api-client==1.12.8
prompt-toolkit==3.0.39
proto-plus==1.22.3
protobuf==4.24.4
ptyprocess==0.7.0
pure-eval==0.2.2
pyarrow==13.0.0
pyasn1==0.5.0
pyasn1-modules==0.3.0
pycparser==2.21
pydantic==1.10.13
pydata-google-auth==1.8.2
Pygments==2.16.1
pyparsing==3.1.1
python-dateutil==2.8.2
python-slugify==8.0.1
pytimeparse==1.1.8
pytz==2023.3.post1
PyYAML==6.0.1
referencing==0.30.2
requests==2.31.0
requests-oauthlib==1.3.1
rpds-py==0.10.6
rsa==4.9
six==1.16.0
soupsieve==2.5
sqlparse==0.4.4
stack-data==0.6.3
text-unidecode==1.3
traitlets==5.11.2
typing_extensions==4.8.0
tzdata==2023.3
uritemplate==4.1.1
urllib3==1.26.17
wcwidth==0.2.8
websockets==11.0.3
yarl==1.9.2
zipp==3.17.0

Solution

  • Although I never found the reason why following these instructions didn't work for me, I was able to work around it using gcloud build.

    So, instead of building my Docker image locally and pushing it to Artifact Repository, as outlined in the link above, I instead do

    gcloud builds submit --region=us-west2 --tag us-west1-docker.pkg.dev/new-life-400922/arapbi/test:latest
    

    and everything works fine.