Docker-Compose with a Node-Postgres API
Using Docker and Docker-Compose to deploy a Node-Postgres API
This project has been more interesting and involved than I thought it would be. What initially looked like a piece of cake ended up being a few steps harder
How it all went down
I started by copy pasting a basic node Dockerfile and changed it so that it would work with my project. — I also added the wait plugin since I new I would be using Postgres in my docker compose.
Next I copy pasted a Node-Postgres docker-compose file, and changed it to work. This was quite the process. Initially I wasn’t sure what arguments to supply to the Postgres instance, but with some looking I found which ones I needed to use. Next, I had to figure out how to initialize the db with the correct tables and extensions installed.
A lot of the struggle that happened in between these steps happened because I kept forgetting to manually reset the docker volume Postgres was using. Once I realized that I had to manually delete the volume each time I restarted docker compose my troubleshooting went more smoothly. Next I had to deploy my node application to my Caprover server.
This was supposed to be a few clicks then done, but I hit a snag. Every time I would make a request to a route I would get a 502 (bad gateway) response.
To make sure the fact that the database wasn’t connected wasn’t interfering with these requests somehow I added a root route to my server’s api that sent a basic “Server is Working” message back on a get request. This, as you may have guessed, did not fix the problem, but it did make testing easier down the line.
I was able to find a bit about this in the Caprover docs that explained that I needed to change the Container HTTP port setting on Caprover to be the port that my container was running on.
Once I changed the port to 3000 in the Caprover dashboard my my “Server Is Working” message displayed like it was supposed to.
Just to test I made a post request to my create user route, and as I expected it told me it couldn’t find the temporary Postgres server host I had put in the env config
Deploying the Postgres Database
This was supposed to be easy. Caprover’s docs said, “One click deploy” so I was sure it would be easy.
I followed the one click deploy process with the correct values for the starting user and database to create.
I grabbed the url for the database and put it into my node app’s env for POSTGRES_HOST. It still didnt work. Looking closely at the one click caprover install I realized that the app is not deployed publicly by default, but that there was an internal host link I could use to connect my app to.
Using this link worked and my app was finally able to connect to the postgres database.
Oh we’re not done yet.
Unfortunately, though my app could connect to the DB, it was missing the configuration file that adds a table and the UID extension I wanted. My requests all sent back the error “collection \users\ not found”
I spent some time looking into how I could supply an additional file to the Caprover one click install or run some SQL remotely on the server, but ultimately came up short.
This is when I realized that the one click install was literally just running a docker container for a simple Postgres install.
This is the same thing my local machine was doing when I ran my docker-compose file, so I could just do the same thing on Caprover
I ended up creating a new directory with a Dockerfile and my init.sql file.
In the file I declared the same env variables that I did in my docker-compose, POSTGRES_USER, POSTGRES_DB, POSTGRES_PORT, POSTGRES_HOST, and gave them the same values my Caprover node app would use to connect to. Finally I added the line:
COPY *.sql /docker-entrypoint-initdb.d/
This would copy my configuration and add it to the folder that Postgres uses to initialize databases.
I deployed the Dockerfile and config file to Github.
I watched the app initialize and deploy and took it’s new url and passed it to the node app’s env var POSTGRES_HOST.
I sent a request from postman and this time it worked.
Since I could possibly use this Postgres database for multiple projects down the line. It would have been prudent to build the table and extension initialization into my web app instead of into the server itself, which I went and fixed later.
In the end, I’m glad that one click install didn’t work. Because it failed I got the chance to further understand how those Caprover one click installs work under the hood.
Checkout the project repo: https://github.com/jewarner57/Node-Postgres-Auth-API