Design Phase – Anonymous secure web form

In the previous post, I described that Formbricks had been chosen as the main platform for serving the anonymous web form, and this was after weighing against the 4 other implementation choices . This blog post will describe how this solution will be designed. Since this is for a privacy focused platform, the non-profit will need to own all of the data, and ensure that submissions are secure while in transit from the user to the non-profit, and at rest.

The main components of the design architecture are outlined in the table below:

Component Function
Formbricks Provides the form functionality, and admin dashboard. Additionally, you also have access to the API if you need custom actions not available through the GUI. This is built on Next.js, which is a JavaScript web framework.
Traefik It is the reverse proxy, which handles encryption and decryption between the client and form server.
PostgreSQL The database platform that’s used to store form data.
Docker compose Serves as the containerization platform for the form application, database, and reverse proxy, allowing it to be self-hosted on a cloud VPS.
VPS server The hosting provider which provides cloud access to the servers which will run the entire application.

 

The main services that will run on the VPS server is PostgreSQL, Traefik, and Formbricks, which are spun up within separate containers using Docker compose. Docker is a containerization platform that allows you to run applications, with all its dependencies, into isolated units called containers. This allows applications to run within their containers rather than directly on the host OS, allowing for better portability. Furthermore with Docker compose, this means you can bundle many different containers together into a single deployable application. These services, which run in their own containers, communicate with each other over the private Docker network, which isn’t public facing. Thus for the server to securely communicate and receive data from the internet, the reverse proxy Traefik is crucial.

A reverse proxy is a server that sits in front of web servers and forwards client (e.g. web browser) requests to those web servers [1]. Since the client form data needs to be sent over the internet in a secure manner, Traefik is used to facilitate this via TLS over port 443 [3]. TLS is a way to encrypt and send data over the internet, allowing users to submit data via a web form securely. Thus, Traefik will serve as the one process in the VPS that accepts encrypted data, decrypting the data, and then forwarding the plain HTTP data to Formbricks. Finally, Formbricks then decides whether to update the PostgreSQL database. As for the VPS, I will be using Google’s free tier called the “Always Free e2-micro instance”, which has the following stats:

  • 0.25 vCPU (increases to 2 vCPU when needed, limited use) [2]
  • 30 GB of Standard Persistent Disk (per month) [2]
  • 1 GB per month of network bandwidth leaving the server (free tier from North America to all destination regions, excluding China and Australia) [2]
  • 1 GB of RAM [2]

Furthermore, the traffic flow is as follows.

  1. The user accesses the form via the browser, which establishes an HTTPS connection to the VPS on port 443.
  2. The browser then encrypts and sends the data to the VPS.
  3. Traefik receives the request and decrypts the payload using its private key, ending the TLS connection.
  4. Traefik sends the plain HTTP request to Formbricks, over the internal Docker network. This network is internal and not public facing.
  5. Formbricks receives and processes the request, and sends an update request to the PostgreSQL database using standard SQL queries.
  6. PostgreSQL then stores the data on the VPS hard disk drive, which is then encrypted at rest by the VPS provider’s disk-level encryption.
  7. Formbricks sends a response back to Traefik, which is then encrypted, and send back to the user’s browser over the same TLS connection. Typical responses usually don’t have a payload, and it’s to tell the client whether the data was sent successfully (status 200) or if there was an issue (status 4XX or 5XX).

 

Figure 1 – Component Diagram

The next post will cover the actual implementation, including the VPS setup, setting up Docker compose, and detailing how this all aligns with the “must have” requirement’s needed for the MVP.

[1] Cloudflare, “What is a reverse proxy? | Proxy servers explained,” Cloudflare Learning Center. [Online]. Available: https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/. [Accessed: May 11, 2026].

[2] Google Cloud, “Compute Engine: Virtual Machines (VMs),” Google Cloud. [Online]. Available: https://cloud.google.com/products/compute. [Accessed: May 11, 2026].

[3] Traefik Labs, “Traefik Documentation,” Traefik Labs. [Online]. Available: https://doc.traefik.io/traefik/. [Accessed: May 11, 2026].

 

Leave a Reply

Your email address will not be published. Required fields are marked *