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:
- Next JS frontend
- Node JS + Express JS backend
- PostgreSQL database
- 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"
This tutorial will be about Ubuntu, but you can try another system of your preference:
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:
Enabling network settings:
Waiting...
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:
Open your security group rules:
We need to edit inbound rules here:
Adding rules for database, backend and frontend, if you have different ports, just use your own values:
This is how the list of rules should look like when you save it:
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"
Here you have several options how to connect, if you did not have ssh key, just click connect button.
Blank tab will be opened and you will see this window:
To connect with SSH:
If you have the following error connecting with SSH using your pem key, this stackoverflow question can help you.
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:
Now we need to configure our environment:
- update the system
sudo apt update
- install nvm
sudo apt install curl
curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
- 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
or you can install node using nvm:
nvm install v16
- install database
sudo apt install postgresql postgresql-contrib
sudo apt update
sudo service postgresql status
sudo service postgresql restart
sudo -u postgres psql
\conninfo
Eventually you should see something like this:
- install pm2
sudo npm i -g pm2
Now we are ready to configure our database to be accessible from our pgAdmin console.
sudo -u postgres psql
\password postgres
Setup your database password here and exit
.
Run this command to open configuration file:
sudo vim /etc/postgresql/14/main/postgresql.conf
Uncomment listen property and set it to listen all:
then enter esc + :wq to write and quit
Next run this command:
sudo vim /etc/postgresql/14/main/pg_hba.conf
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
then enter esc + :wq to write and quit
Let's check our configuration, run this commands:
sudo systemctl restart postgresql
ss -nlt | grep 5432
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.
Next we can try to connect our server to p4Admin.
Use your public address as a host name:
Give it a meaningful name:
And setup the connection details:
Congratulations, our database is connected to the console!
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
Les's add start command eval $(ssh-agent) to ensure the agent is running when you open a terminal.
cd ~
vim .bash_profile
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
Exist and connect again, you should see this new info:
Check the connection by running this command:
ps -auxc | grep ssh-agent
For my projects I created the structure:
mkdir projects
cd projects
mkdir .ssh
cd .ssh
Here I am going to store my ssh keys.
ssh-keygen -t ed25519 -b 4096 -C "{username@emaildomain.com}" -f {ssh-key-name}
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.
Add key to your bitbucket/git:
Cloning for the first time the fingerprint will be created and you will be prompted to enter a passphrase.
Cloning existing backend with ssh:
Cloning existing 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!
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>
Run pm2 save to save the current list of processes.
And let's check now if everything is correct:
Backend is working :)
Frontend is working too:
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! Now you have your full-stack app up and running on EC2 instance with database connected to the pgAdmin console!
Top comments (3)
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.
This is really helpful for me. Thanks for your effort..
I am glad if it helped you, happy coding! :)