I had previously made a tutorial about how to create a Fullstack app and now I'm going to show how to dockerize this app and deploy it to Heroku.
I...
For further actions, you may consider blocking this person and/or reporting abuse
Thanks for sharing this detailed guide and honestly, I am a big fan of Heroku when it comes to deploy a containerized application. However, since last November, it has become very frustrating to deploy containers with this PaaS platform.
Yes, Heroku has turned all of its free tier plans into paid ventures. But luckily, someone recommended me Container as a Service product of Back4App. Indeed, I followed this article blog.back4app.com/how-to-deploy-do... to quickly deploy Docker container for free compared to paid options of Heroku. I think you should also include freemium CaaS vendors in your upcoming article to help startups and novice developers.
Thanks for the feedback Mia!
I love the suggestion, I will definitely take a look and consider it for a next post. This post here is very out of date so I am planning to write a new one and I definitely need a PaaS platform with a free tier.
Let me know if you'd like to see any specific technology or stack and I might consider it for the next post too :)
i cannot understand one thing -
when we run docker on our computers, we have to specify "port mapping" e.g. docker run my-image -p 4000:3000
now we can access it on localhost:4000 (3000 is the docker container's port, 4000 host port)
so why do we need to process.env.PORT on our nodejs app ?
all we need to do is have node listen on any port (lets say 3000), then specify "port mapping" -p $PORT:3000 ($PORT is the port which heroku provides)
am i missing something?
The objective of having the
PORT
environment variable in your node application is that you can specify a dynamic port to run your app and that is the best way to make sure that your container and your app are using the same port to communicate with each other. We usually run the docker application through adocker-compose.yaml
file, or maybe your application can be managed by an orchestrator which will for sure require a dynamic environment variable to define the ports.In conclusion, basically having a port defined via an environment variable provides a unified way to declare which port your app should be running.
to make sure that your container and your app are using the same port to communicate with each other.
actually, i wanted to run 3 containers on the same app -
i ultimately went on to make 3 separate heroku apps, one for each container, which works absolutely fine.
what if i wanted to run all 3 containers on the same app?
but in heroku, if i tie one container to the $PORT, what about the other 2 containers?
so i didnt want to run all the containers on the $PORT provided by heroku.
Do you have a git repo with your code for the containerized reverse proxy?
github.com/shameekagarwal/gql
three different heroku apps frontend (in react, served via nginx), backend (in expressjs), and a reverse proxy (nginx)
I don't think Heroku is an effective microservices orchestration tool. You might want to try something like Okteto or Fly.io. (A lot of people like Heroku because it's a free VPS; the ones I mentioned are too.) I've got a working example of the reverse proxy in docker code up on Okteto. Fly works sometimes and other times it's tricky. I didn't bother trying to get it to work there. But here's a link to a recent poast and it also has the git repo and the example. Have a good one.
dev.to/bronifty/nginx-reverse-prox...
thanks!!
my example does work..but heroku isnt for container orchestration..just deploy containers..
Why install npm if the installation is written in the dockerfile. For this, docker was created so that you do not need to install anything on the machine, in docker everything should be installed by itself at startup.
Yes, that is true Sam. But in the end, the result will be the same while doing that in the dev environment because, as we have a volume pointing to the local file system, any installation in the container or in the local system will end up creating the node_modules folder in the local file system anyway.
There are implementations to avoid that, but for simplicity matters of this article, I decided to keep it as is.
Can you post a link to this implementation?
Good tutorial. I followed step by step. But I got an error when execute the last step: heroku open. :(
2020-10-30T17:33:26.078663+00:00 app[web.1]: /app/node_modules/mongodb-core/lib/topologies/server.js:431
2020-10-30T17:33:26.078664+00:00 app[web.1]: new MongoNetworkError(
2020-10-30T17:33:26.078665+00:00 app[web.1]: ^
2020-10-30T17:33:26.078665+00:00 app[web.1]:
2020-10-30T17:33:26.078666+00:00 app[web.1]: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017
2020-10-30T17:33:26.078667+00:00 app[web.1]: at TCPConnectWrap.afterConnect as oncomplete {
2020-10-30T17:33:26.078667+00:00 app[web.1]: name: 'MongoNetworkError',
2020-10-30T17:33:26.078667+00:00 app[web.1]: errorLabels: [Array],
2020-10-30T17:33:26.078668+00:00 app[web.1]: [Symbol(mongoErrorContextSymbol)]: {}
2020-10-30T17:33:26.078668+00:00 app[web.1]: }]
2020-10-30T17:33:26.078670+00:00 app[web.1]: at Pool. (/app/node_modules/mongodb-core/lib/topologies/server.js:431:11)
2020-10-30T17:33:26.078670+00:00 app[web.1]: at Pool.emit (node:events:327:20)
2020-10-30T17:33:26.078670+00:00 app[web.1]: at /app/node_modules/mongodb-core/lib/connection/pool.js:557:14
2020-10-30T17:33:26.078671+00:00 app[web.1]: at /app/node_modules/mongodb-core/lib/connection/connect.js:39:11
2020-10-30T17:33:26.078671+00:00 app[web.1]: at callback (/app/node_modules/mongodb-core/lib/connection/connect.js:261:5)
2020-10-30T17:33:26.078672+00:00 app[web.1]: at Socket. (/app/node_modules/mongodb-core/lib/connection/connect.js:286:7)
2020-10-30T17:33:26.078672+00:00 app[web.1]: at Object.onceWrapper (node:events:434:26)
2020-10-30T17:33:26.078672+00:00 app[web.1]: at Socket.emit (node:events:327:20)
2020-10-30T17:33:26.078673+00:00 app[web.1]: at emitErrorNT (node:internal/streams/destroy:194:8)
2020-10-30T17:33:26.078673+00:00 app[web.1]: at emitErrorCloseNT (node:internal/streams/destroy:159:3)
2020-10-30T17:33:26.078673+00:00 app[web.1]: at processTicksAndRejections (node:internal/process/task_queues:80:21) {
2020-10-30T17:33:26.078674+00:00 app[web.1]: errorLabels: [ 'TransientTransactionError' ],
2020-10-30T17:33:26.078674+00:00 app[web.1]: [Symbol(mongoErrorContextSymbol)]: {}
2020-10-30T17:33:26.078674+00:00 app[web.1]: }
Hello Rodrigo, I am so sorry for the delay, I think I missed your comment before.
Based on the logs you sent, it seems like you don't have the
MONGODB_URI
environment variable defined in your application, so the app is trying to connect to a database inlocalhost:27017
that does not exist.Hi Thiago,
Thank you very much for this amazing tutorial. It took me quite a while but I was able to dockerize my node app with Angular instead of React, although when I open the app it shows Application Error. I checked the logs and it throws "Error R15 (memory quota vastly exceeded)" I was googling and I think is because NodeJS is taking too much space from the dynos. I don't know how to fix this issue, hopefully you could give me some insight. I will really appreciate your help a lot.
Thank you very much.
Luis Romero
Hi Romero, I am sorry but I think I missed your comment before.
I would need to take a look at how you have defined your app because it seems like you might have a memory leak going on.
We can chat more about it if you want, send me an email or share the repo with me if you are comfortable and I can try to give you a hand with that :)
ey nice tut idk if things changed but this is what u wanna do at the end
Thank you!
I guess if you are already in the context of your heroku app in your terminal, you don't really need to pass the --app tag.
Yeah i tried doing that without the —app tag and it said use -a or - app /: but its ok i got it to work! Thx loads m8
Deploy to Heroku in Container
Hi, thanks for sharing the deployment guideline.
I am trying to deploy a dockerized react app in heroku. But after pushing the image, heroku fails to bind port. I've tried extending timeout to 120s, 180s, still no change. Can you suggest me what can I do now?
Thank you savior
Thank you for this !! 🙇🏻♂️