I was working on a NextJS project recently. For those who don't know, NextJS is the most popular React framework with in-built SSR support.
Now, people use SSR for many reasons but the most common ones are as follows.
- To render pages on the server-side and hence reduce latency on the client-side.
- To protect their APIs.
I needed NextJS and SSR for the 2nd benefit that is, protecting my API. I had two Dokku apps for my project - frontend
and backend
and I had to make it such that frontend
can access backend
internally. Also, the backend
should not be available publically.
I found that the easiest way to do so is by using Docker networks. The idea here is to create a network and assign that network to both frontend
and backend
apps. With this, both apps will be able to access each other's networks.
To do so, we ssh to the server running our Dokku apps. Then we create a Docker network.
docker network create mynetwork
You can verify that the network has been created as follows.
docker network list
Once that is done, we simply assign it to our frontend
and backend
apps.
dokku docker-options:add frontend deploy "--net mynetwork"
dokku docker-options:add backend deploy "--net mynetwork"
After this, just restart your apps.
dokku ps:restart frontend
dokku ps:restart backend
frontend
and backend
will now be able to access each other's network internally. To verify, just enter the frontend
container and try to access the backend
network as follows.
dokku enter frontend
# once entered
curl http://backend.web.1
The URL backend.web.1
comes from the container name. We know that Dokku renames the containers as <app name>.<process name>.<number>
. Since you will probably be serving the API from the web
process, we use the URL backend.web.1
.
From that curl request, we should get the data that the backend serves at route /
. Note that in the above case it is assumed that backend is running the server at port 80.
If you have a different port that serves your backend, you should be able to access it normally.
# in frontend container
curl http://backend.web.1:5000
The next step is disabling public access to the backend. Dokku's documentation says to do this by running the following command.
dokku domains:disable backend
This gives a random high port to your backend
app. You can either use it or just use a custom random port. For example, here I forward port 5000 in the container to host's 5426.
dokku proxy:ports-set backend http:5426:5000
This allows you to access the backend
app from http://<serverIP>:5426
as well as access it internally in the frontend from http://backend.web.1:5000
.
Dokku has no way to completely disable exposing a web service to the public so this is your best bet. If you do want to do so, you should be able to do it by modifying the NGINX configuration. But I believe that is not needed for most applications.
That's it. By doing everything in this article, you can access your Dokku apps internally without leaking it publically.