DISCLAIMER: ngrok is a paid service. This blog post is not sponsored by or affiliated with ngrok in any way.
What are Stripe Webhooks?
Recently, I worked on a project that involved taking payments using Stripe. Not having worked with Stripe before, I imagined a fairly straightforward process of setting up API calls to Stripe to handle what we needed. Turns out, while that is part of the equation, Stripe also offers a powerful feature called webhooks.
Webhooks are just a fancy name for API calls made from Stripe to your application. So now we have a two-way street of communication: it's not just our app talking to Stripe, Stripe is also talking back. This is just what we needed for our use-case.
We decided to use Stripe's Checkout feature, which sends users to Stripe to input their payment information and then Stripe redirects them back to our app. This allowed us to skip the hassle of integrating the Stripe payment form directly on our site. When the payment is completed, Stripe sends a webhook event to our app so we can process the order. Once that's done, our app returns a 200 response code to Stripe and our user gets redirected to our app's order success page.
Now, this all sounds great, but when we're developing, our local server can't accept requests via the internet. After all, the server only exists on our local machine- it's not on the public internet. So what can we do? We have to find a way to allow our local development server to be accessible via the internet. This is where ngrok comes to the rescue.
Using Ngrok in a Docker Development Environment
Ngrok is a service that provides a public URL through which one can access a local development server. When we run the ngrok software on our development machine, it creates a tunnel that routes incoming requests to that public URL to our local server. In our case, our development environment is set up with Docker, so it required a tiny bit more work to configure. Let's get started.
Download the ngrok client binary
Go to the download page on the ngrok site. We're going to be running ngrok inside a Linux Docker container, so download the Linux binary regardless of your machine's OS. For this example, we're going to put our ngrok-related files in a directory called ngrok in our project.
Create a configuration file called ngrok.conf with the following contents:
log: stdoutYour ngrok authentication token is available in the ngrok dashboard under the "Auth" section. The web_addr line allows us to open the ngrok web inspector in our browser. The log line allows us to see the ngrok log when we run docker-compose logs ngrok.
Note: ngrok says to use the ngrok authtoken command to set the token. This would work fine if we were running ngrok on our host machine. Since we're running ngrok in a Docker container, we're going to set the token in a configuration file instead.
Configure a new container for ngrok with Docker Compose
We're using Docker Compose to set up our development environment, so adding an additional container for running ngrok is a breeze. Add the following lines to your docker-compose.yml under the services sectionngrok:
- ./ngrok:/code/ command: /code/ngrok http : --subdomain= -config=/code/ngrok.conf links:
- php ports:
- 4040:4040In the above configuration, should be replaced by the name of the Docker Compose service that is running your application server. The --subdomain flag is an option if you have a paid account, which allows you to reserve one or more subdomains that, combined with ngrok.io, create your public URL. Without this option, ngrok will create a random URL for you each time it runs. (ngrok docs) As an example, say my service is called php, the app listens on port 8000, and the subdomain is eriks-app. The line would then look like:command: /code/ngrok http php:8000 --subdomain=eriks-app config=/code/ngrok.conf
Build and run the ngrok container
Use docker-compose up ngrok to build and run this new container. To verify that ngrok is running, go to localhost:4040 in your browser and you should see the ngrok web inspector.Congratulations! ngrok is up and running and now requests to your public URL will be routed to your local app server. You can test by opening the public URL in your browser or using CURL to make an API request to your app.Now that we have ngrok running and our public URL, all we have to do is configure the service that is providing our webhooks (Stripe, in our case) to use the ngrok public URL as the application URL.
Going Forward with Stripe
Using this setup, I was not only able to easily work with Stripe Webhooks, but also, by my simply sharing the new docker-compose.yml and ngrok-related files, the other developers on my team were able to just run docker-compose up and quickly have ngrok ready to go, without needing to download the binary or deal with any configuration themselves. We were then all able to continue with our Stripe integration work using webhooks.