Redeploying a Node.js .tar.gz Project on AWS EC2 Using CloudShell
Assume you already have a Node.js application deployed to an AWS EC2 instance from a .tar.gz archive. You have since made changes locally and want to update the deployed files to match your latest version.
If you are familiar with building a project locally and restarting a Windows service, the idea is similar: transfer the updated application, replace the deployed files, and restart the server process.
With AWS, you can perform these steps using AWS CloudShell and Systems Manager Session Manager (SSM), provided your EC2 instance is configured for SSM access.
1. Package the Updated Project Locally
From your project directory, create an archive containing the files required to run the application:
Bash
tar -czf app.tar.gz dist package.json package-lock.jsonAdjust the archive contents to match your project structure. Include other required files (such as Prisma assets, configuration templates, or migration files) where applicable. Do not package secrets or local development dependencies unnecessarily.
For example, excluding unneeded files:
Bash
tar -czf app-backup.tar.gz \
--exclude='.env' \
--exclude='.env.*' \
--exclude='node_modules' \
--exclude='.git' \
--exclude='app.tar.gz' \
.1.a. Debugging: tar: dist: Cannot stat: No such file or directory
If you encounter a compression error on your local machine:
Plaintext
tar: dist: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errorsThis indicates that the tar command cannot find the dist directory in your current working directory. In a Node.js project, this usually happens because the production build has not been generated yet, the project uses a different output directory, or you are executing the command from the wrong folder.
1.b. Confirm Your Current Directory
Run:
Bash
pwd
ls -laConfirm that you are inside the root directory of your Node.js project (where package.json resides). If you are in the wrong directory, navigate to your project root:
Bash
cd /path/to/your/project1.c. Check Whether the Build Directory Exists & Generate the Production Build
Run ls -la to see if dist exists. If your project requires source files instead of a dist build output, archive the source files directly:
Bash
tar -czf app.tar.gz \
app.js \
package.json \
package-lock.json \
prisma.config.ts \
prisma/ \
src/ \
helpers/Wait for the build/archive to complete successfully, then verify that the archive was created:
Bash
ls -laNote: You can rename app.tar.gz to match your projected output filename if you use versioning (e.g., app-v2.tar.gz).
2. Upload the Archive to AWS CloudShell
Now that the application archive has been created successfully, upload it to AWS CloudShell:
- Open the AWS Management Console and launch CloudShell in the AWS Region where your deployment resides.
- In the CloudShell interface, open Actions → Upload file.
- Select
app.tar.gzfrom your local computer and upload it.
Once the upload completes, verify that the file exists in CloudShell:
Bash
ls -lh app.tar.gz2.a. Confirm the Archive Location in CloudShell
Verify the exact path of your uploaded archive in CloudShell:
Bash
ls -lh ~/app.tar.gzThe expected location is /home/cloudshell-user/app.tar.gz. Ensure the filename matches what you use in subsequent transfer commands.
Important: CloudShell and your EC2 instance have separate filesystems. Uploading the archive to CloudShell does not automatically transfer it to your EC2 instance.
3. Transfer the Archive to the EC2 Instance
There are several ways to transfer files from CloudShell to an EC2 instance. A reliable option is to use an Amazon S3 bucket as an intermediary, particularly when the instance is managed through AWS Systems Manager (SSM).
3.a. Upload the Archive from CloudShell to Amazon S3
From CloudShell, upload the archive to your S3 deployment bucket:
Bash
aws s3 cp ~/app.tar.gz \
s3://YOUR-BUCKET/deployments/app.tar.gz \
--region [region-code](Replace YOUR-BUCKET and the --region flag with your actual bucket name and AWS Region).
3.b. Verify the S3 Upload
Verify that the file is present in the S3 bucket before proceeding:
Bash
aws s3 ls s3://YOUR-BUCKET/deployments/ \
--region [region-code]3.c. Transfer the File from S3 to EC2 via SSM (or Directly on EC2)
You can trigger the download on EC2 using SSM Run Command directly from CloudShell:
Bash
aws ssm send-command \
--instance-ids i-YOUR-INSTANCE-ID \
--document-name AWS-RunShellScript \
--parameters 'commands=["aws s3 cp s3://YOUR-BUCKET/deployments/app.tar.gz /tmp/app.tar.gz --region your-region"]'Alternatively, connect directly to your EC2 instance (via SSM Session Manager or SSH) and run:
Bash
aws s3 cp \
s3://YOUR-BUCKET/deployments/app.tar.gz \
/tmp/app.tar.gz \
--region [your-region]Note: The EC2 instance must have the AWS CLI installed and an attached IAM role with permissions to read from the target S3 bucket.
4. Back Up the Existing Application
Before replacing deployed files, create a backup of the current application on the server.
Get Claud Watari’s stories in your inbox
Join Medium for free to get updates from this writer.
For example, if your application lives at /opt/app:
Bash
sudo tar -czf /tmp/app-backup.tar.gz \
-C /opt appVerify that the backup was created successfully:
Bash
ls -lh /tmp/app-backup.tar.gzNote: Storing backups on the same instance is useful for fast rollbacks, but off-instance storage (like S3) is recommended for production disaster recovery.
5. Inspect and Extract the Updated Application
5.a. Debugging: tar: Cannot open: No such file or directory
If you attempt to inspect or extract the archive on EC2 and encounter:
Plaintext
tar (child): /tmp/app.tar.gz: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting nowThis means the tar command cannot locate /tmp/app.tar.gz on the current machine. Confirm whether you are connected to the EC2 instance or still inside CloudShell.
If needed, start an SSM session to connect to your EC2 instance from CloudShell:
Bash
aws ssm start-session --target i-YOUR-INSTANCE-ID --region YOUR-REGION-CODE5.b. Verify the Archive on EC2
Once connected to the EC2 instance, confirm the archive exists in /tmp:
Bash
ls -lh /tmp/app.tar.gzInspect its contents without extracting:
Bash
tar -tzf /tmp/app.tar.gz5.c. Extract the Archive
Extract the archive into your target deployment directory:
Bash
sudo tar -xzf /tmp/app.tar.gz \
-C /opt/appCaution: Extracting an archive over an existing directory does not delete files that were removed in the new local build. For production deployments, using versioned directories with symlinks is recommended.
6. Install Dependencies and Prepare Prisma
Because the archive contains package.json and package-lock.json but excludes node_modules, install the required dependencies on the EC2 instance:
Bash
cd /opt/app
npm ci --omit=dev(If your project requires dev-dependencies to generate build artifacts or Prisma clients, run npm ci without --omit=dev).
6.a. Generate Prisma Client
If your application uses Prisma, generate the client for the target environment:
Bash
npx prisma generate6.b. Verify Environment Variables & Database Migrations
- Ensure production environment variables (
.env) are present on the server (do not package.envfiles inside your build archives). - Execute database migrations (
npx prisma migrate deploy) only when required by the release and after verifying target database safety.
7. Restart the Node.js Service
If your application process is managed by systemd, restart the service:
Bash
sudo systemctl restart appVerify the status of the service:
Bash
sudo systemctl status app --no-pager(If using PM2, Docker, or another process manager, use the corresponding restart commands).
8. Verify the Deployment
A successful service restart does not automatically guarantee full application health.
8.a. Inspect Service Logs
Check the latest logs for runtime errors or missing configurations:
Bash
sudo journalctl -u app -n 100 --no-pager8.b. Health Checks & Endpoint Validation
Verify the following checklist:
- [ ] Service starts clean without crashing.
- [ ] Database connectivity is active.
- [ ] Prisma client connects without schema mismatch.
- [ ] Required environment variables are loaded.
- [ ] HTTP health checks or critical API endpoints return
200 OK.
9. Final Thoughts
Redeploying a Node.js application on EC2 involves more than simply copying files and restarting a process. Archive integrity, file paths, dependency management, environment security, and process management all play key roles.
For high-availability production environments, consider automated CI/CD pipelines (e.g., AWS CodeDeploy, GitHub Actions) or containerized workflows to simplify rollbacks and deployment reliability.







