Photo by Jon Tyson on Unsplash

3 Easy Ways How To Deploy Static Application on AWS


I did a post earlier on how to host a static website with S3 and CloudFront in AWS, this tutorial shows other ways to host a simple static website with Docker and without Docker in an EC2 instance. However, rather than just talk about it, I choose to create them. I believe that will do better to drive home the point especially for those who find using Elastic Beanstalk a little too expensive for their static website.

Also, as a bonus, I showed how to use Nginx web server to proxy and serve the website traffic request using a domain name.

First, we will start with hosting the static website in AWS S3, and then, we will proceed to EC2 instance and serve with Nginx web server, then we will host with docker.

Ready? let’s go.

method 1

We will start our deployment using AWS S3. This is pretty the same with the previous tutorial, so, you can skip this stage to the next method of using EC2 and docker to host the static website.

Search for S3 and select the Create Bucket.

Create S3 bucket

Enter a unique name for your S3 bucket, the bucket should not be use anywhere in the world, so you have to be creative in creating the name. Select your preferred region.

name the S3 bucket

Uncheck the Block All Public Access option. We allow this for the demo, in production, you will like not allow public access and use the ACL for access. However, that is beyond the scope of this tutorial.
Also, check the acknowledgement from AWS too.

Then click the Orange Create Bucket button.

uncheck all public access to host static website

Once the bucket is created we will need to upload our static website code into the S3 bucket. You can download the demo code from free-css . You can also clone the repository from here.

Under the new window,find the objects tab, then click Upload

Upload static website source code to s3

Select all the elements in the root directory of the static application source code and upload to S3. Do not put the root directory directly into S3.

Upload static website source code

Click the Upload button, then wait a few minutes for the application source code to upload into S3.

You will see Succeeded like below.

Successful S3 upload

Now, we need to set the permissions for S3 to allow the Static Application setting have visibility of the source code we upload earlier. We will add the GetObject and PutObject into the Bucket Policy.

create bucket policy

First, select Permissions from the options, Scroll down to find the Bucket Policy.

create permissions for S3

Click the Edit under Bucket Policy.

Edit the bucket policy

Click the Add New Statement

Add policy statement to S3

Use the Filter actions to find S3, then scroll down to find GetObject and PutObject from the list of permissions in the statement.

PutObject statement for S3 policy

Your final Bucket policy should look like the below. You can also copy and paste this code in the json window.

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
            "Resource": "arn:aws:s3:::sample-static-site-ytess0w/*"

Click the Create Policy button.

enable the static web hosting properties in s3

This makes the difference to host static website on S3 and EC2 with docker.

Click on the Properties in the Bucket name settings panel.

Set up properties in S3

Scroll down to find the Static Website Hosting feature. Click Edit.

Edit the static website hosting setting in S3

Click the Enable and the under Hosting Type, select Host a Static Website. Use index.html for the Index Document. Then click the Create button.

Enable the static website hosting with host a static website option

You will find the URL for the S3 static application at the bottom of your page.

Static website URL

Copy and paste the URL on your web browser to and you will find the application.

Visit the page.

You can also checkout how to serve the static application with AWS CloudFront service.

method 2

Now let’s move to the second method. We will use the Nginx web server installed in an Ubuntu EC2 server to host the static website, and lastly docker. If you have not installed Nginx, run the command on your terminal to install it.

sudo apt install nginx

Transfer your files from your local machine to remote with the command:

scp -r /path/on/local/machine username@IPaddress:/destination/on/remote/machine

You can also choose to clone the source code into your server.

git clone  organization/[email protected]

Once you get the source code into your remote machine, print out the working directory.

print working directory in EC2 to see static website source code

Create and configuration for Nginx.

sudo nano /etc/nginx/sites-enabled/staticapp

Paste configuration below change the root directory into the working directory from the pwd output.

server {

    location / {
        root   /paste/your/directory/here;
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /paste/your/directory/here;

Add the root directory of the static website

Save and close the editor with Ctrl X Y Enter.

After that, check that no syntax in the configuration

sudo nginx -t

And then restart nginx to pick the changes

sudo service nginx restart

Once you did that, grab your URL and paste in the web browser to show you web app serving with your domain from your EC2 instance.

method 3

The third method use docker container to host our static website. We will use Nginx as our base image and the put it in the /usr/share/nginx/html directory in the docker container.

Create a Dockerfile in the root of your directory.

sudo nano Dockerfile

Then paste the configuration inside the file. Save and close the nano editor using Ctrl X Y Enter.

FROM nginx

WORKDIR /usr/share/nginx/html

RUN rm -r /usr/share/nginx/html/

COPY . /usr/share/nginx/html

Create a Docker file for static website

Build and run the docker image

docker build -t imageName .
docker run --name containerName -d -p hostPort:80 imageName

#check the status of the container
docker ps -a

Once that is done, you can also create an Nginx proxy redirect to serve the application.

Create a configuration file like the one in method 2, and paste the configuration below there. Modify the server_name and proxy_pass details to your own.

server {

        location / {
              proxy_pass         http://localhost:3000;
              proxy_http_version 1.1;
              proxy_set_header   Upgrade $http_upgrade;
              proxy_set_header   Connection keep-alive;
              proxy_set_header   Host $host;
              proxy_cache_bypass $http_upgrade;
              proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header   X-Forwarded-Proto $scheme;
              proxy_set_header   X-Real-IP $remote_addr;
Use Nginx to proxy the static website host

Once that is done, check that no syntax and also restart the Nginx web server. Then access your application from the web server using the URL you created

Access the static website host with Docker in EC2

Kudos on a job well done. I am positive you have more tools in your arsenal to deploy static website using AWS S3 storage, AWS EC2, and docker. We started the journey by hosting our static website AWS S3, and then we used the EC2 instance with Nginx web server to proxy user requests, and lastly we containerized the static website with Docker.

  1. ERROR: 403 Forbidden Code: AccessDenied Message, AccessDenied
    SOLUTION: Create the bucket policy, or check that the bucket policy is properly created with the GetObject and PutObject permission.
  1. ERROR: 404 Not Found
    Code: NoSuchKey
    Message: The specified key does not exist.
    Key: index.html

    SOLUTION: This means S3 can not find the index.html file in the bucket. Check the content you uploaded into S3 and make sure index.html is at the root of the bucket.






Leave a Reply

Your email address will not be published. Required fields are marked *