🔳 <テーマ>Chatgptで、システム構築
使用技術: Spring Initilizer, Springboot, IntelliJ, GraalVM for Native Image, Docker Container
使用環境 : Mac M1(Arm), Unbuntu 20 on AWS
🔳<やりたい事>
Spring Initilizar(https://start.spring.io/) でSpringbootアプリ作成して、
→ それを手元のMac M1マシン(Arm basis)にGraalVM CEを使い、Native Image化して(開発環境はIntelliJ)
→ それをMac上で、Docker Containerに変換して
→ 出来上がったDocker ContainerをAWS上のUbuntu20インスタンスのDocker環境に移動して
→ VMインスタンス上で、portをTCP8080にマップして、Docker Containerを起動させて、
→ 手元MacPCから、アクセスして起動確認する。
🔳<結果>成功
naive@naive ~ % curl http://152.xxx.xxx.xxx:8080/hello
Hello from Native Image!%
🔳<所感>
Chatgptを駆使する事で、複数の技術が介在するシステム構築を瞬間的に構築可能であることが判明した。
Chatgptに投げ込んだ指示文は下記。
I am now writing instruction sheet how to setup Docker Container including Native Image on Ubuntu Server on OCI.
Can you give me it ?
The procedure might be below.
1. On Mac PC(Arm based M1), Springboot app is created using Spring intilizer. (app name is "demo".)
2. Springapp is converted to native image file using GraalVM CE on my Mac PC.(IntelliJ environment)
3. Native image file is compiled to Docker Image on my Mac PC. (Rancher Desktop is used.)
4. Docker image is copied to the home directory of Ubuntu 20 (Arm base) running on AWS. (I used termius SSH client)
5. On Unbuntu VM, docker environment setup is done and firewall is opened(TCP8080) along with VCN Network Security setup.
6. Docker images is run on Unbuntu VM on AWS. (Show the command to run docker image and map the port to TCP8080).
7. I access to docker from my Mac PC's browser using "http://<server ip address>:8080/hello "
I believe that that is all but if something is missing, please add.
=====================
<下記詳細>
Create the Spring Boot Application with IntelliJ (Using Gradle)
Spring Initilizar (https://start.spring.io/)
・Open IntelliJ IDEA.
・Create a New Project:
・Choose Spring Initializr as the project type.
・Select your installed JDK (Java 17 or later).
・Configure the following settings:
・Group: com.example
・Artifact: demo
・Name: demo
・Build System: Gradle
・Language: Java
・Spring Boot Version: 3.4.3 (or the latest stable 3.x)
・Select Dependencies:
At a minimum, add Spring Web.
Optionally add Spring Boot Actuator.
Finish and Open the Project.
・Configure the Application:(On IntelliJ)
In src/main/resources/application.properties, add:
server.address=0.0.0.0
This ensures that when running inside a container, your app listens on all network interfaces.
2.
Configure the Gradle Build for Native Image
Open the generated build.gradle file and update it as follows:
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'org.graalvm.buildtools.native' version '0.10.5'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
// We are using dynamic linking, so do NOT force static linking.
graalvmNative {
binaries {
main {
// No extra buildArgs needed.
}
}
}
3.
Build the Native Image Using GraalVM
Install GraalVM CE:
Download GraalVM CE for Java 17 from Oracle GraalVM Downloads and install it.
Install the Native Image Component:
gu install native-image
Build the Native Image:
Open a terminal in your project root (or use IntelliJ’s Terminal) and run:
./gradlew clean nativeCompile
The native executable (typically named demo) will be generated under build/native/nativeCompile/.
4.
Build a Docker Image Containing the Native Image (Using Rancher Desktop)
Create a Multi-Stage Dockerfile:
Save the following content as Dockerfile in your project root:
# -------------------------------------------
# 1) Builder Stage: Compile the Native Image
# -------------------------------------------
FROM ghcr.io/graalvm/native-image:latest as builder
# Switch to root to install required utilities
USER root
RUN microdnf install -y findutils \
|| yum install -y findutils \
|| dnf install -y findutils \
|| (apt-get update && apt-get install -y findutils) \
|| apk add --no-cache findutils
WORKDIR /app
COPY . .
RUN chmod +x gradlew
RUN ./gradlew clean nativeCompile
# -------------------------------------------
# 2) Final Stage: Create the Runtime Container
# -------------------------------------------
FROM ubuntu:22.04
# Install zlib to ensure libz.so.1 is available (required by the dynamically linked native image)
RUN apt-get update && apt-get install -y libz1
# Copy the native executable from the builder stage
COPY --from=builder /app/build/native/nativeCompile/demo /app/demo
# Expose port 8080
EXPOSE 8080
ENTRYPOINT ["/app/demo"]
Build the Docker Image:
Open a terminal in your project directory and run:
docker build -t demo --no-cache .
(Rancher Desktop provides the Linux container environment on your Mac.)
Export the Docker Image to a Tar File:
Once the build is complete, run:
docker save -o demo.tar demo
5.
Transfer the Docker Image to Your Ubuntu Server (ARM-based on AWS)
Ensure your Ubuntu VM is ARM-based:
This is very important. Your target Ubuntu server on AWS must be running on ARM architecture (e.g., AWS Graviton instances). Verify the architecture by running:
uname -m
It should return something like aarch64 or arm64.
Transfer the Image:
Use SCP (or your preferred secure transfer tool) to copy demo.tar to your Ubuntu server:
scp demo.tar your_username@your-ubuntu-server-ip:~/
(You can use an SSH client like Termius.)
Part II – On Your AWS Ubuntu Server (ARM-based)
6.
Install and Set Up Docker on the Ubuntu Server
Update the Package Index:
sudo apt-get update
Install Required Packages:
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
Add Docker’s Official GPG Key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Add Docker’s Repository:
sudo add-apt-repository \
"deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable"
Update the Package Index Again:
sudo apt-get update
Install Docker Engine:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
Start and Enable Docker:
sudo systemctl start docker
sudo systemctl enable docker
(Optional) Allow Your User to Run Docker Commands Without Sudo:
sudo usermod -aG docker $USER
Then log out and log back in (or reboot).
Verify Docker Installation:
docker --version
sudo docker run hello-world
7.
Open Port 8080 on Your Ubuntu Server
Using UFW (if enabled):
sudo ufw allow 8080/tcp
sudo ufw status
Using iptables:
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo apt-get install -y iptables-persistent
sudo netfilter-persistent save
8.
Load and Run the Docker Image on the Ubuntu Server
Load the Docker Image:
sudo docker load -i ~/demo.tar
Verify that the image is loaded:
sudo docker images
Run the Docker Container:
sudo docker run --rm -p 8080:8080 demo:latest
This command maps the container’s port 8080 to the server’s port 8080.
Test Your Application: From the Ubuntu server (or from another machine that can reach it), run:
curl http://<your-ubuntu-server-ip>:8080/hello
You should see the expected output, for example: "Hello from Native Image!"
9.
Access the Application from Your Mac
Open your web browser on your Mac and navigate to:
http://<your-ubuntu-server-ip>:8080/hello
You should see your Spring Boot application’s response.
🔳 Summary
On Your Mac (M1):
・Create a Spring Boot app using IntelliJ with Gradle.
・Configure the Gradle build for native image support.
・Build the native image using GraalVM.
・Package the native image in a Docker image using a multi-stage Dockerfile (with Ubuntu 22.04 as the final stage).
・Export the Docker image as demo.tar.
Transfer the Image:
・Use SCP to copy demo.tar to your AWS Ubuntu server.
・Important: The Ubuntu VM must be ARM-based (e.g., AWS Graviton) to match the image architecture.
On Your AWS Ubuntu Server (ARM-based):
・Install and set up Docker.
・Open port 8080 in the firewall.
・Load the Docker image from demo.tar and run the container.
・Test the application locally, then access it remotely from your Mac.