DEV Community

Alain Airom
Alain Airom

Posted on

Second Experience with Apple Containers!

Another step with Apple containers!

Introduction

My initial blog post detailing my first practical experience with Apple containerization technology sparked a flurry of discussion and significant inquiries from my colleagues. The central question raised — and the point of subsequent internal debate — was whether this capability possessed the necessary maturity and reliability for industrial-scale deployment. My answer to that is an unequivocal “YES.” This certainty stems from further comprehensive testing, which has solidified my conviction that this capacity provided by Apple is not only viable today but is also poised for accelerated development and is undeniably here to stay.

Tests

For my first (new) test, I wrote a vey basic “Hello World” app in Go.

package main

import (
 "fmt"
)

func main() {
 // Simple application logic
 fmt.Println("Hello from the Go container!")
}
Enter fullscreen mode Exit fullscreen mode

Then I made a Dockerfile to build an image which runs this code.

FROM golang:1.22-alpine AS builder

ENV CGO_ENABLED=0

WORKDIR /app

COPY go-hello.go .

RUN go build -o app -ldflags "-s -w" go-hello.go

FROM scratch

ENTRYPOINT ["/app"]

COPY --from=builder /app/app /app

Enter fullscreen mode Exit fullscreen mode

For the first step, I used Podman to build an image 👇

podman build -t go-hello .
podman run go-hello
# for Docker
docker build -t go-hello .
docker run go-hello
Enter fullscreen mode Exit fullscreen mode

Running the image gives the following output;

Hello from the Go container! 
Enter fullscreen mode Exit fullscreen mode

OK, now I build the same image with the “container” from Apple on my MacOS.

# start the engine
container system start
container builder start --cpus 8 --memory 32g

# build the image
container build --tag go-test --file Dockerfile .
...

[+] Building 8.2s (9/9) FINISHED                                                                                                                                                 
 => [resolver] fetching image...docker.io/library/golang:1.22-alpine                                                                                                        0.0s
 => [internal] load .dockerignore                                                                                                                                           0.0s
 => => transferring context: 2B                                                                                                                                             0.0s
 => oci-layout://docker.io/library/golang:1.22-alpine@sha256:1699c10032ca2582ec89a24a1312d986a3f094aed3d5c1147b19880afe40e052                                               2.2s
 => => resolve docker.io/library/golang:1.22-alpine@sha256:1699c10032ca2582ec89a24a1312d986a3f094aed3d5c1147b19880afe40e052                                                 0.1s
 => => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B                                                                                    0.0s
 => => sha256:4861bab1ea04dbb3dd5482b1705d41beefe250163e513588e8a7529ed76d351c 127B / 127B                                                                                  0.0s
 => => sha256:fa1868c9f11e67c6a569d83fd91d32a555c8f736e46d134152ae38157607d910 297.86kB / 297.86kB                                                                          0.0s
 => => sha256:52f827f723504aa3325bb5a54247f0dc4b92bb72569525bc951532c4ef679bd4 3.99MB / 3.99MB                                                                              0.0s
 => => extracting sha256:52f827f723504aa3325bb5a54247f0dc4b92bb72569525bc951532c4ef679bd4                                                                                   0.1s
 => => extracting sha256:fa1868c9f11e67c6a569d83fd91d32a555c8f736e46d134152ae38157607d910                                                                                   0.0s
 => => sha256:90fc70e12d60da9fe07466871c454610a4e5c1031087182e69b164f64aacd1c4 66.29MB / 66.29MB                                                                            0.3s
 => => extracting sha256:90fc70e12d60da9fe07466871c454610a4e5c1031087182e69b164f64aacd1c4                                                                                   1.8s
 => => extracting sha256:4861bab1ea04dbb3dd5482b1705d41beefe250163e513588e8a7529ed76d351c                                                                                   0.0s
 => => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1                                                                                   0.0s
 => [internal] load build context                                                                                                                                           0.0s
 => => transferring context: 159B                                                                                                                                           0.0s
 => [linux/arm64/v8 builder 1/4] WORKDIR /app                                                                                                                               0.4s
 => [linux/arm64/v8 builder 2/4] COPY go-hello.go .                                                                                                                         0.0s
 => [linux/arm64 builder 3/4] RUN go build -o app -ldflags "-s -w" go-hello.go                                                                                              1.8s
 => [linux/arm64/v8 stage-1 1/1] COPY --from=builder /app/app /app                                                                                                          0.0s
 => exporting to oci image format                                                                                                                                           0.1s
 => => exporting layers                                                                                                                                                     0.1s
 => => exporting manifest sha256:4357214a4637b5297da08bb3cc84ebcdd0fa89b9b4208cb60bbba859faa1ef04                                                                           0.0s
 => => exporting config sha256:7d618301e78cf16c98f0d472556bb8c883bbf4d87ea675811716385c041fbdd0                                                                             0.0s
 => => exporting manifest list sha256:1c9e4da40926ae74bc397abd23acf07ee2dfb28ee0c14f275b960ba1a695e32d                                                                      0.0s
 => => sending tarball                                                                                                                                                      0.0s
Successfully built go-test:latest  
Enter fullscreen mode Exit fullscreen mode

Let’s run it 🏃‍♀️

container run  --rm go-test
Hello from the Go container! 
Enter fullscreen mode Exit fullscreen mode

Comparing my images by using Podman Desktop 🏅

This application could be deployed, for instance on my Minikube cluster with no problem!

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-hello-deployment
  namespace: apps 
  labels:
    app: go-hello
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-hello
  template:
    metadata:
      labels:
        app: go-hello
    spec:
      containers:
      - name: go-hello-container
        image: go-hello:latest 
        imagePullPolicy: Never
Enter fullscreen mode Exit fullscreen mode
# for my specific configuration
minikube start --driver=podman --kubernetes-version=v1.28.0

# for a specific namespace
kubectl create namespace apps

kubectl apply -f go-hello-deployment.yaml
Enter fullscreen mode Exit fullscreen mode

Nice, now let’s build a Java application! Below is the simple version of “Hello World” written in the most simple Java application ever 😶

public class HelloWorld {
    public static void main(String[] args) {
        // Print the greeting to standard output
        System.out.println("Hello, Java World from the container!");
    }
}
Enter fullscreen mode Exit fullscreen mode

And the adequate Dockerfile 🧺

FROM eclipse-temurin:21-jdk-alpine AS builder

WORKDIR /app

COPY HelloWorld.java .

RUN javac HelloWorld.java

FROM eclipse-temurin:21-jre-alpine

WORKDIR /app

COPY --from=builder /app/HelloWorld.class .

CMD java -cp . HelloWorld
Enter fullscreen mode Exit fullscreen mode

Now let us build and run this code!

container build --tag java-hello --file Dockerfile .

...
[+] Building 2.2s (12/12) FINISHED                                                                                                                                               
 => [resolver] fetching image...docker.io/library/eclipse-temurin:21-jdk-alpine                                                                                             0.0s
 => [resolver] fetching image...docker.io/library/eclipse-temurin:21-jre-alpine                                                                                             0.0s
 => [internal] load .dockerignore                                                                                                                                           0.0s
 => => transferring context: 2B                                                                                                                                             0.0s
 => oci-layout://docker.io/library/eclipse-temurin:21-jdk-alpine@sha256:89517925fa675c6c4b770bee7c44d38a7763212741b0d6fca5a5103caab21a97                                    0.0s
 => => resolve docker.io/library/eclipse-temurin:21-jdk-alpine@sha256:89517925fa675c6c4b770bee7c44d38a7763212741b0d6fca5a5103caab21a97                                      0.0s
 => oci-layout://docker.io/library/eclipse-temurin:21-jre-alpine@sha256:990397e0495ac088ab6ee3d949a2e97b715a134d8b96c561c5d130b3786a489d                                    0.0s
 => => resolve docker.io/library/eclipse-temurin:21-jre-alpine@sha256:990397e0495ac088ab6ee3d949a2e97b715a134d8b96c561c5d130b3786a489d                                      0.0s
 => [internal] load build context                                                                                                                                           0.0s
 => => transferring context: 297B                                                                                                                                           0.0s
 => CACHED [linux/arm64/v8 stage-1 1/3] WORKDIR /app                                                                                                                        0.0s
 => CACHED [linux/arm64/v8 builder 1/4] WORKDIR /app                                                                                                                        0.0s
 => CACHED [linux/arm64/v8 builder 2/4] COPY HelloWorld.java .                                                                                                              0.0s
 => CACHED [linux/arm64 builder 3/4] RUN javac HelloWorld.java                                                                                                              0.0s
 => CACHED [linux/arm64/v8 stage-1 2/3] COPY --from=builder /app/HelloWorld.class .                                                                                         0.0s
 => exporting to oci image format                                                                                                                                           0.3s
 => => exporting layers                                                                                                                                                     0.0s
 => => exporting manifest sha256:f468154e8f4d3d7830c0a9294df9a518004c2b5e431b28a41eb12cbf9ac1f006                                                                           0.0s
 => => exporting config sha256:0aac090feabd2c49d6de93877ac5029dc5ae0ba39df3c343e27e286385d42fa5                                                                             0.0s
 => => exporting manifest list sha256:c004a43800e34f66948cf45a56dcb6b484e7ade4c8dd510c3c0d6ea20a3d3b81                                                                      0.0s
 => => sending tarball                                                                                                                                                      0.3s
Successfully built java-hello:latest 


> container run --rm java-hello
Hello, Java World from the container!
Enter fullscreen mode Exit fullscreen mode

Et voilà 🍾

Conclusion

As established through my initial and subsequent testing, I am convinced that Apple containerization is a fundamental game-changer in the deployment landscape. This technology doesn’t just offer an interesting alternative; it delivers the operational flexibility and robust architecture required to build and confidently deploy industry-grade applications, signaling a significant shift in how we approach enterprise development.

Links

Top comments (0)