If we copy the image to Artifact Registry:
resource "google_artifact_registry_repository" "cloud-run-test" {
location = "europe-central2"
repository_id = "cloud-run-test"
format = "DOCKER"
}
$ terraform apply
$ docker pull cloudnativelabs/whats-my-ip
$ docker tag cloudnativelabs/whats-my-ip europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/whats-my-ip
$ docker push europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/whats-my-ip
resource "google_cloud_run_v2_service" "cloud-run-test" {
name = "cloud-run-test"
location = "europe-central2"
template {
containers {
image = "europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/whats-my-ip"
}
}
}
resource "google_artifact_registry_repository" "cloud-run-test" {
location = "europe-central2"
repository_id = "cloud-run-test"
format = "DOCKER"
}
$ terraform apply
$ gcloud logging read 'logName:projects/PROJECT_ID/logs/run.googleapis.com%2F' --format 'text(logName, textPayload, timestamp)' --project PROJECT_ID --freshness=5m
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fvarlog%2Fsystem
text_payload: Container called exit(2).
timestamp: 2023-12-09T04:57:12.567151674Z
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fstderr
text_payload: /home/server: line 1: syntax error: unexpected "("
timestamp: 2023-12-09T04:57:11.574154Z
os/arch
or:
a.sh
:
set -eu
image=cloudnativelabs/whats-my-ip
registry=https://registry-1.docker.io
curl_args=(-sS -H 'Accept: application/vnd.docker.distribution.manifest.v2+json')
scope=repository:$image:pull
token=`curl -sS "https://auth.docker.io/token?service=registry.docker.io&scope=$scope" | jq -r .token`
curl_args+=(-H "Authorization: Bearer $token")
manifest=`curl "${curl_args[@]}" "$registry/v2/$image/manifests/latest"`
config_digest=`echo "$manifest" | jq -r .config.digest`
config=`curl "${curl_args[@]}" -L "$registry/v2/$image/blobs/$config_digest"`
os=`echo "$config" | jq -r .os`
architecture=`echo "$config" | jq -r .architecture`
echo "$os/$architecture"
$ bash a.sh
linux/amd64
file
:
$ docker container create cloudnativelabs/whats-my-ip
$ docker cp 97bd786fbc2dd1df6925121ae8c0febebaf1a6f8785c10a7a7237e5799791289:/home/server /tmp/server
$ docker rm 97bd786fbc2dd1df6925121ae8c0febebaf1a6f8785c10a7a7237e5799791289
$ file /tmp/server
/tmp/server: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=edc3254ee8543cb3d51767295b041bc44368d286, with debug_info, not stripped
$ od -t x1z /tmp/server | head -3
0000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 >.ELF............<
0000020 02 00 03 00 01 00 00 00 40 a7 09 08 34 00 00 00 >........@...4...<
0000040 14 01 00 00 00 00 00 00 34 00 20 00 07 00 28 00 >........4. ...(.<
From the description:
Go web server running on port 8080
sh /home/server
:
$ docker run --rm -it cloudnativelabs/whats-my-ip sh /home/server
/home/server: line 1: syntax error: unexpected "("
$ docker history --no-trunc cloudnativelabs/whats-my-ip | less
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:7be89ad1e6ef4ef4eac70f5be5fca9501eea2159a01f29b2b407690cfdcc0c1e 6 years ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/home/server"] 0B
<missing> 6 years ago /bin/sh -c #(nop) COPY file:eadac022277eddb995689c668b68561cef126d9b5ca9a3992a2b2b31a1ae1b18 in /home/ 4.84MB
<missing> 6 years ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 6 years ago /bin/sh -c #(nop) ADD file:c9ecd8ff00c653fb652ad5a0a9215e1f467f0cd9933653b8a2e5e475b68597ab in / 1.11MB
A simple go
server (not the original implementation):
server.go
:
package main
import (
"fmt"
"net/http"
)
func root(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
fmt.Fprintf(w, "hello world (go)\n")
}
func main() {
http.HandleFunc("/", root)
fmt.Printf("Server running...\n");
http.ListenAndServe(":8080", nil)
}
Dockerfile
:
FROM alpine:3.18 AS build
COPY server.go .
RUN apk add go && go build server.go
FROM alpine:3.18
COPY --from=build /server /home/server
CMD ["/bin/sh", "-c", "/home/server"]
$ docker build -t i .
$ docker history --no-trunc i | less
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:a9eb6fb2e9ed7adb06b830feda760219c43fd6b6f05c517bb5dd1941e0a7f80e 21 minutes ago CMD ["/bin/sh" "-c" "/home/server"] 0B buildkit.dockerfile.v0
<missing> 21 minutes ago COPY /server /home/server # buildkit 6.68MB buildkit.dockerfile.v0
<missing> 5 months ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 5 months ago /bin/sh -c #(nop) ADD file:1da756d12551a0e3e793e02ef87432d69d4968937bd11bed0af215db19dd94cd in / 7.33MB
The CMD
line differs a bit:
-/bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/home/server"]
+CMD ["/bin/sh" "-c" "/home/server"]
$ docker tag i europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i
$ docker push europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i
resource "google_cloud_run_v2_service" "cloud-run-test" {
name = "cloud-run-test"
location = "europe-central2"
template {
containers {
image = "europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i"
}
}
}
$ terraform apply
$ gcloud logging read 'logName:projects/PROJECT_ID/logs/run.googleapis.com\%2F' --format 'text(logName, textPayload, timestamp)' --project PROJECT_ID --freshness=5m
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fvarlog%2Fsystem
text_payload: Default STARTUP TCP probe succeeded after 1 attempt for container "i-1" on port 8080.
timestamp: 2023-12-09T07:02:32.756159Z
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fstdout
text_payload: Server running...
timestamp: 2023-12-09T07:02:32.743640Z
Running a 32-bit go
server on Cloud Run:
Dockerfile
:
FROM alpine:3.18 AS build
COPY server.go .
RUN apk add go && GOARCH=386 go build server.go
FROM alpine:3.18
COPY --from=build /server /home/server
CMD ["/bin/sh", "-c", "/home/server"]
$ docker build -t i32 .
$ docker tag i32 europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i32
$ docker push europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i32
resource "google_cloud_run_v2_service" "cloud-run-test" {
name = "cloud-run-test"
location = "europe-central2"
template {
containers {
image = "europe-central2-docker.pkg.dev/PROJECT_ID/cloud-run-test/i32"
}
}
}
$ terraform apply
$ gcloud logging read 'logName:projects/PROJECT_ID/logs/run.googleapis.com\%2F' --format 'text(logName, textPayload, timestamp)' --project PROJECT_ID --freshness=5m
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fvarlog%2Fsystem
text_payload: Container called exit(2).
timestamp: 2023-12-09T07:53:43.173579304Z
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fstderr
text_payload: /home/server: line 2: syntax error: unexpected "("
timestamp: 2023-12-09T07:53:42.174998Z
---
log_name: projects/PROJECT_ID/logs/run.googleapis.com%2Fstderr
text_payload: /home/server: line 1: ?ELFAAABCA??: not found
timestamp: 2023-12-09T07:53:42.174974Z
$ docker run --rm -it i32 sh -c 'apk add file; file /home/server'
...
/home/server: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=-UmeOax9gDsURrJp1IOc/CXhXTcfUnoQh7DBkw3r2/kOV85W8Lgl0qM7iB94ov/ExdX4uzfHMS2PUt1AdAO, with debug_info, not stripped
$ docker run --rm -it i32 sh -c 'apk add coreutils; od -t x1z /home/server | head -3'
...
0000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 >.ELF............<
0000020 02 00 03 00 01 00 00 00 d0 c9 0a 08 34 00 00 00 >............4...<
0000040 14 01 00 00 00 00 00 00 34 00 20 00 07 00 28 00 >........4. ...(.<
It seems like Cloud Run doesn't expect 32-bit binaries, and when faced with one it falls back to sh
(sh /path/to/executable
).