How to test nginx changes on Heroku fast!

midjourney promt: a stopwatch in space in the style of Barbara Kasten --v 5 --ar 16:9

If you are like me, changing things in a Nginx config comes with a lot of try end error. If you are using Heroku (with the nginx buildpack), testing out small changes in the nginx file can take a lot of time due to the fact that for every change you need to do a commit and a new deployment of the app.

After a lot of "update nginx config" commits, I thought about a way to reduce the feedback loop and came up with a solution.

Here are the steps you need to do to change the config and get direct feedback without waiting. Keep in mind, that all changes we do are not persisted. This method is just for trying out different configs and then transfer them to the config file in your local project.

The key to this method is the Heroku Exec command. With this command, you can connect to a running dyno. I suggest to only use this method in a dev/stage apps. I case you break something, a simple will new deployment of the app resets everything. Also keep in mind that the SSH tunnel might only be open for 1h.

1. Install Vim

First, we need to add the Vim buildpack to the app. This is nessesary because by default the dyos don't have a text editor beside ed. Follow the instructions here or just do:

heroku buildpacks:add https://github.com/carloluis/heroku-buildpack-vim-a [app-name]

In theory, you could also use heroku-buildpack-nano, but it did not work for me.

2. Connect to Running Dyno

In contrast to heroku run, heroku ps:exec in not spawning a new one-off dyno but is connecting to a running one. You can specify the dyno with --dyn=[dyno-name]. By default, it is connecting to web.1

heroku ps:exec -a [app-name]

Keep in mind that changes are only applied to one dyno. So if you have multiple, and you test later, you might reach a dyno without the changes. My suggestion is to scale done to one dyno for this method.

3. Change Config

You can now just use vim to change the config

vim config/nginx.conf

I theory you could also change the ERB template, but it seems that we don't have access the ENV variables when doing heroku ps:exec. I we head we could transfor the ERB file via erb config/nginx.conf.erb > config/nginx.conf

4. Test and Reload Config

The last step is to reload the config. Before that, you can test the configuration

    bin/nginx -p . -c config/nginx.conf -t
    bin/nginx -p . -c config/nginx.conf -s reload
  • -p prefix: set prefix path (default: /tmp/nginx/)
  • -c filename: set configuration file (default: conf/nginx.conf)
  • -s signal: send signal to a master process: stop, quit, reopen, reload

Conclusion

Now open the app in the browser and check if the applied changes work. Remember to transfer the changes to your codebase after verifying they work. I hope this small guide will help you get a faster feedback loop when working with Heroku and nginx.

Another and probably better way would be of curse to spin up a local docker container with nginx and test your settings there.

I hope this little guide will help you the next time you are wrestling with nginx on heroku.