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 -
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
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
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
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
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
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
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.