DEV Community

Victoria
Victoria

Posted on • Updated on

Deploy a full-stack app with PostgreSQL on AWS EC2

Cover
Hello, devs! In this article, I invite you on an interesting journey into AWS full-stack development. I had a task to create a dev environment for a full-stack application on EC2 which was created by another developer, the stack is the following:

  1. Next JS frontend
  2. Node JS + Express JS backend
  3. PostgreSQL database
  4. AWS EC2

As a secondary task I need to establish an access to the dev database from the pgAdmin console.

I decided to write an article as a walk-through and documentation for other devs as well. It was a bit challenging to find and gather all the necessary pieces together. And eventually, AWS EC2 deploy is much much easier to do than a lot of YouTube videos or online tutorials are explaining.

That being said, let's deploy an app from scratch together!

Step 1 - Create your EC2 instance

Go to AWS console and find EC2 service. Click "Launch instance"

ec2 dashboard

This tutorial will be about Ubuntu, but you can try another system of your preference:
instance configuration

Choose the size of your instance, for demo and test env you can pick micro or small, depends on the size of your app.

You also can create a key for a ssh connection, I already have one, so I will skip this part:

Create ssh key

Enabling network settings:

Enabling network settings

Waiting...

pending

running

Congratulation, we have launched our EC2 instance!

Step 2 - Security rules

Lots of tutorials love to skip this part, but I need all your attention here, because without these settings your app will not be accessible. Including your database from your pgAdmin.

Open your instance's dashboard and go to the Security tab:

Instance dashboard

Open your security group rules:

rules

We need to edit inbound rules here:

inbound rules

Adding rules for database, backend and frontend, if you have different ports, just use your own values:

new rules

This is how the list of rules should look like when you save it:

saved rules

And here we are done with our instance configuration, let's proceed with our server configuration.

Step 3 - Environment configuration

Go back to the instance and click "Connect"

connect btn

Here you have several options how to connect, if you did not have ssh key, just click connect button.

connect options

Blank tab will be opened and you will see this window:

connection window

To connect with SSH:

ssh connect

If you have the following error connecting with SSH using your pem key, this stackoverflow question can help you.

bug with ssh

I will use Hyper terminal configured as git bash (solved most of the problems btw), as you can see the window is almost the same:

SSH git bash

Now we need to configure our environment:

  • update the system
sudo apt update
Enter fullscreen mode Exit fullscreen mode
  • install nvm
sudo apt install curl
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
Enter fullscreen mode Exit fullscreen mode
  • install node (you can install any version you want, but 16 is the most stable imho)
curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
sudo apt install nodejs
node  -v
Enter fullscreen mode Exit fullscreen mode

or you can install node using nvm:

nvm install v16
Enter fullscreen mode Exit fullscreen mode
  • install database
sudo apt install postgresql postgresql-contrib
sudo apt update
sudo service postgresql status
sudo service postgresql restart
sudo -u postgres psql
\conninfo
Enter fullscreen mode Exit fullscreen mode

Eventually you should see something like this:

connected to database

  • install pm2
sudo npm i -g pm2
Enter fullscreen mode Exit fullscreen mode

Now we are ready to configure our database to be accessible from our pgAdmin console.

sudo -u postgres psql
\password postgres
Enter fullscreen mode Exit fullscreen mode

Setup your database password here and exit.

Run this command to open configuration file:

sudo vim /etc/postgresql/14/main/postgresql.conf
Enter fullscreen mode Exit fullscreen mode

Uncomment listen property and set it to listen all:

set up listen all

then enter esc + :wq to write and quit

Next run this command:

sudo vim /etc/postgresql/14/main/pg_hba.conf
Enter fullscreen mode Exit fullscreen mode

Place following setting at the end of the file:

#IPv4 Addresses
host all all 0.0.0.0/0 md5
#IPv6 Addresses
host all all ::0/0 md5
Enter fullscreen mode Exit fullscreen mode

then enter esc + :wq to write and quit

Let's check our configuration, run this commands:

sudo systemctl restart postgresql
ss -nlt | grep 5432
Enter fullscreen mode Exit fullscreen mode

This should give response as running on global 5432, i.e. 0.0.0.0:5432. This means that psql is now enabled for remote access.

access is enabled

Next we can try to connect our server to p4Admin.

Use your public address as a host name:

host name

register server 1

Give it a meaningful name:

name

And setup the connection details:

connection details

Congratulations, our database is connected to the console!

Congratulations

Step 4 - Connecting our Git/Bitbucket with SSH

First of all, let's configure our ssh agent

sudo apt update && sudo apt install openssh-client
Enter fullscreen mode Exit fullscreen mode

Les's add start command eval $(ssh-agent) to ensure the agent is running when you open a terminal.

cd ~
vim .bash_profile
Enter fullscreen mode Exit fullscreen mode

add the following:

SSH_ENV="$HOME/.ssh/agent-environment"

function start_agent {
    echo "Initialising new SSH agent..."
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    #ps ${SSH_AGENT_PID} doesn't work under cywgin
    ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi
Enter fullscreen mode Exit fullscreen mode

Exist and connect again, you should see this new info:

ssh agent connection

Check the connection by running this command:

ps -auxc | grep ssh-agent
Enter fullscreen mode Exit fullscreen mode

connection established

For my projects I created the structure:

mkdir projects
cd projects 
mkdir .ssh
cd .ssh
Enter fullscreen mode Exit fullscreen mode

Here I am going to store my ssh keys.

ssh-keygen -t ed25519 -b 4096 -C "{username@emaildomain.com}" -f {ssh-key-name}
Enter fullscreen mode Exit fullscreen mode

When prompted to Enter passphrase, you can either provide a password or leave the password empty. If you input a password, you will be prompted for this password each time SSH is used, such as using Git command that contact Bitbucket Cloud (such as git push, git pull, and git fetch). Providing a password will prevent other users with access to the device from using your keys.

generating a key

Add key to your bitbucket/git:

adding a key

add identity

1

Cloning for the first time the fingerprint will be created and you will be prompted to enter a passphrase.

Cloning existing backend with ssh:

clone backend with ssg

Cloning existing frontend with ssh:

Cloning frontend with ssh

Don't forget to run npm install in each folder and set up env variables properly, remember that your backend is no longer on localhost!

example of env vars

Done, we have connected our version control and cloned repos.
In case the current user is no longer valid to develop on this account just delete the key and change config and generate a new key.

Step 5 - Start our project with pm2

Run build command for frontend app first, then head to the backend and frontend folders and run the command:

pm2 start npm --name "process name" -- <start script name>
Enter fullscreen mode Exit fullscreen mode

Run pm2 save to save the current list of processes.

pm2 run project

And let's check now if everything is correct:

Backend is working :)

EC2 node js deployed

Frontend is working too:

Frontend

If you have a problem when process like "build" stuck, try to check and kill all the processes and run build command again.

If you have a bug when your instance is unreachable - reboot it and try again. Since we are using t2 micro some processes can overload CPU and memory.

congratulations

Congratulations! Now you have your full-stack app up and running on EC2 instance with database connected to the pgAdmin console!

Top comments (3)

Collapse
 
gimjudge profile image
Daniel Baker

Super awesome. I was trying to set something up for hobby work and I was going the RDS route with portgres. DevOps not being a strong point, I was struggling. Your post really simplified the setup for me as it's much more similar to my home ubuntu dev server.

This was a triumph.
I'm making a note here:
Huge success.
It's hard to overstate
my satisfaction.

Collapse
 
trojandeveloper profile image
Vinnie Stracke

This is really helpful for me. Thanks for your effort..

Collapse
 
hugaidas profile image
Victoria

I am glad if it helped you, happy coding! :)