Sitemap
Claud Watari

Claud Watari

{ null }

Redeploying a Node.js .tar.gz Project on AWS EC2 Using CloudShell

6 min readOct 27, 2026

--

Press enter or click to view image in full size

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.json

Adjust 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 errors

This 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 -la

Confirm 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/project

1.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 -la

Note: 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.gz from your local computer and upload it.

Once the upload completes, verify that the file exists in CloudShell:

Bash

ls -lh app.tar.gz

2.a. Confirm the Archive Location in CloudShell

Verify the exact path of your uploaded archive in CloudShell:

Bash

ls -lh ~/app.tar.gz

The 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 app

Verify that the backup was created successfully:

Bash

ls -lh /tmp/app-backup.tar.gz

Note: 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 now

This 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-CODE

5.b. Verify the Archive on EC2

Once connected to the EC2 instance, confirm the archive exists in /tmp:

Bash

ls -lh /tmp/app.tar.gz

Inspect its contents without extracting:

Bash

tar -tzf /tmp/app.tar.gz

5.c. Extract the Archive

Extract the archive into your target deployment directory:

Bash

sudo tar -xzf /tmp/app.tar.gz \
-C /opt/app

Caution: 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 generate

6.b. Verify Environment Variables & Database Migrations

  • Ensure production environment variables (.env) are present on the server (do not package .env files 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 app

Verify 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-pager

8.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.

--

--