"It works on my machine." The four most famous last words in software engineering.
The Chat app was running perfectly on https://data.chat. Files were uploading, and images were showing up. But there was a catch: the S3 bucket was public. In modern development, "public" is a major security risk. To secure the app, I had to make the bucket private and switch to S3 Presigned URLs.
That one "simple" security upgrade triggered a domino effect of deployment nightmares—from VPC identity crises to Maven dependency black holes.
Before fixing the code, I had to move the server to a more secure environment. I meticulously designed a custom VPC (Virtual Private Cloud) for the Chat backend, complete with specific subnets and routing tables.
chat-vpc. 
To implement private access, I needed the S3Presigner class from the AWS SDK v2. This is where the Java compiler decided to stage a protest.
On my local machine, Maven pulls the SDK effortlessly. On the EC2 instance, inside a Docker container, the compiler suddenly acted like it had never seen the AWS SDK in its life.
S3Presigner classes—is 3.5MB.libs/ and mapped via systemPath in the pom.xml, I'm still fighting the [ERROR] cannot find symbol ghost.When you are deep in "dependency hell," you cannot trust your build tools blindly. You have to go to the file system.
ls -l to ensure that the file I thought was there actually existed and had the correct size.3578909 bytes (3.5MB) was the only way to prove to myself that the library was ready for the compiler. If the file is 2048 bytes, your build will fail every single time.Once you get the app to build and the network to behave, you hit the final boss: Docker Port Mapping.
When running a containerized app on EC2, you have three layers of "doors" that must align perfectly for chatapp.chat to load:
8080.80 (or 443 for SSL).The Confusion: It is incredibly easy to mix up the Host:Container syntax. If you map it as 8080:80 instead of 80:8080, your app will run internally, but the outside world will see a "Connection Refused."
The transition from "it works on my machine" to "it works securely in the cloud" is the ultimate test. It’s the moment you stop being just a coder and start being a System Architect.
I’m still in the trenches with this Maven error, but every failure is just another piece of the puzzle. Securing your user's data with S3 Presigned URLs is worth the gray hair. Stay tuned for the fix!
"VPC ID is correct, and the ports are mapped, but that Maven 'S3Presigner' ghost is still haunting my terminal—time for a very large coffee before Round 2."
Welcome to the cloud. Bring your patience—and double-check your VPC ID.