Deploying a Microservices E-Commerce Application on AWS Using Shell Scripting

4
calendar_today agoschedule4 min read
— Originally published at devopswithpmpk.hashnode.dev

This article was originally published on Hashnode and is being republished here.

It covers deploying a microservices-based e-commerce application on AWS using Shell Scripting, including server setup, service configuration, and application deployment.

Over the past few days, I learned Shell Scripting and decided to apply everything I had learned by building a complete project from scratch to gain real hands-on experience.

My goal wasn't just to deploy the RoboShop e-commerce application on AWS using Shell Scripting. I also wanted to understand what happens behind the scenes—how services start, how they communicate with each other, how to automate repetitive deployment tasks, and most importantly, how to troubleshoot issues when things go wrong.

Throughout this project, I learned how to debug deployment issues by analyzing HTTP status codes, checking Nginx logs, application logs, and database logs, identifying whether the problem was in the upstream or downstream service, and writing proper deployment logs to make troubleshooting easier.

More than the automation itself, the debugging experience gave me strong hands-on knowledge of application deployment, troubleshooting, and real-world infrastructure automation.


What is the RoboShop E-Commerce Project?
RoboShop is a microservices-based e-commerce application consisting of around 10 services, including Frontend, Catalogue, User, Cart, Shipping, Payment, MongoDB, MySQL, Redis, RabbitMQ, and Dispatch. Each service has its own responsibility and communicates with other services to complete the order flow.

This project is a great way to understand how multiple services are deployed, connected, and managed in a real-world environment.


Application Components
The RoboShop application is built using multiple technologies, with each service having a specific responsibility.

Service and Technology
Mongodb (NoSQL Database)
Catalogue (Node.js)
Redis (Caching Server)
User (Node.js)
Cart (Node.js)
Mysql (SQL Database)
Shipping (Java)
Rabbitmq (Message Broker)
Payment (Python)
Dispatch (Go (Golang))
Frontend (Nginx (Reverse Proxy))


How Requests Flow
The Frontend uses Nginx as a reverse proxy. Instead of clients communicating directly with backend services, every request first reaches Nginx. Based on the requested URL, Nginx forwards the request to the appropriate backend service.

location /api/catalogue/ {
    proxy_pass http://catalogue:8080/;
}

location /api/user/ {
    proxy_pass http://user:8080/;
}

location /api/cart/ {
    proxy_pass http://cart:8080/;
}

location /api/shipping/ {
    proxy_pass http://shipping:8080/;
}

location /api/payment/ {
    proxy_pass http://payment:8080/;
}

Using a reverse proxy provides several benefits:

Clients communicate only with Nginx, not directly with backend services.

The actual backend server details remain hidden.

Nginx routes requests to the correct service based on the URL.

It also makes it easier to manage load balancing, SSL termination, and routing from a single entry point.


Deployment Approach
Although the services are built using different technologies such as Node.js, Java, and Python, the deployment process is almost the same for every service.

The deployment flow includes:

  • Installing the required runtime

  • Creating the application user and directory

  • Downloading and extracting the application

  • Installing application dependencies

  • Configuring a systemd service

  • Loading the database schema (where required)

  • Starting and enabling the service

Since this workflow was common across almost every service, I moved all the reusable functions into a single common.sh file and reused it across all deployment scripts. This reduced duplicate code and made the scripts much easier to maintain.


What I Automated
During this project, I automated the following tasks:

✅ Validated every command using Linux exit codes (0 = Success, non-zero = Failure) to stop execution immediately if a step failed.

✅ Implemented idempotency, allowing the scripts to be executed multiple times safely.

✅ Moved all reusable deployment logic into a common common.sh file.

✅ Automated application deployment for all services, including runtime installation, dependency installation, and systemd configuration.

✅ Automated EC2 instance creation using AWS CLI.

✅ Automated Route53 DNS record creation using AWS CLI.

✅ Generated detailed log files for every deployment step to simplify troubleshooting.

✅ Performed root user validation before executing privileged operations.

Instead of repeating the same steps for every server, I automated the entire deployment using Shell Scripting. This made deployments consistent, repeatable, and much faster.


Debugging Challenges
This was the most interesting part of the project and where I learned the most. Writing the scripts was only one part, Troubleshooting the issues taught me how to debug deployments by following logs and tracing requests step by step instead of guessing.

After deploying the application, I expected everything to work. However, when I opened the application, the catalogue products were not loading.

Here's how I approached the issue:

Checked the browser's HTTP status code and found a 504 Gateway Timeout.

Looked at the Nginx access.log on the frontend and found that
=> Nginx forwarded the request to the upstream (backend) service.

=>The upstream service did not return a response within the configured timeout. (waiting for something to get from database)

Verified that the Catalogue service was running using systemctl status

Checked the Catalogue service logs using: journalctl -u catalogue -f

The logs showed that the Catalogue service couldn't connect to MongoDB.

Logged into the MongoDB server and found that the MongoDB service was stopped.

Started the MongoDB service, and the Catalogue service immediately began working.


💡What I learned:
This issue taught me not to jump to conclusions or restart services blindly. Instead, I learned to follow the request flow—from the browser, to Nginx, to the application logs, and finally to the database—to identify the actual root cause.

This debugging process gave me much more confidence in troubleshooting real deployment issues and understanding how different services interact in a microservices environment.


🚀 What's Next?
In the next part of this project, I'll automate the application configuration using Ansible, a configuration management tool. This will help eliminate manual server configuration and make deployments even more consistent and scalable.


🎉 Final Thoughts
This project helped me turn my Shell Scripting knowledge into practical experience. Along the way, I learned a lot by intentionally stopping services, analyzing logs, and troubleshooting the resulting issues.I gained valuable hands-on experience in automation, deployment, and debugging. I'll continue building more projects to strengthen my practical skills and gain even more real-world experience.

If you're interested in exploring the implementation, feel free to check out the complete project source code from below.
https://github.com/pavankumar0816/shell-roboshop-common


I am including a few screenshots of the deployed application:

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

AWS Certifications Are a Building Block, Not the Final Destination

Ijay - Jun 16

10 Proven Ways to Cut Your AWS Bill

rogo032 - Jan 16

How to Reduce Your AWS Bill by 50%

rogo032 - Jan 27

Learn AWS for Free Hands On Without Getting Charged

Ijay - Feb 24

The Audit Trail of Things: Using Hashgraph as a Digital Caliper for Provenance

Ken W. Algerverified - Apr 28
chevron_left
121 Points4 Badges
1Posts
0Comments

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!