FRP - an open source alternative to ngrok

If you want to expose a service from your LAN to the internet and you can’t open ports, you can use ngrok, or its open source alternative FRP.


The server will be the middle man between your service and the person visiting.

Install FRP server (called frps).

I installed my instance on Docker using Ansible and the cloverzrg/frps-docker image:

- name: frps tunnel server side
  hosts: vps
  gather_facts: false
  become: true

  - name: frps
      name: tunnel
      image: cloverzrg/frps-docker
        - name: UserDefinedBridge
      purge_networks: yes
      restart_policy: "always"
      - /opt/docker/
      - "7700:7700"
      - "28443:28443"
      - "28080:28080"
        traefik.enable: "true"
        ansible: "true"
        traefik.http.routers.tunneladmin.entrypoints: "https"
        traefik.http.routers.tunneladmin.service: "tunneladmin"
        traefik.http.routers.tunneladmin.rule: "Host(``)"
        traefik.http.routers.tunneladmin.tls: "true"
        traefik.http.routers.tunneladmin.tls.certresolver: "letsencrypt" "7500"

FRP comes with a web interface running on port 7500 which I secure behind Traefik.

The server will listen for connections on TCP/7700. Services will be exposed either on port 28080 (http) or 28443 (https).


bind_port = 7700
token = xxx

vhost_http_port = 28080
vhost_https_port = 28443

dashboard_port = 7500
dashboard_user = ricky
dashboard_pwd = zzz

tcp_mux = true
max_pool_count = 10


Let’s assume your client runs an HTTP server locally on port 443.

Download the client


Create frpc.ini

server_addr =
server_port = 7700
token = xxx
tcp_mux = true
tls_enable = true

type = https # this is the service that will define which port will be used publicly (see server config)
local_port = 443 # this is the port of the service you want to expose
custom_domains =

Run frpc -c frpc.ini

Your service should be available at

For any custom domain to work, you need a wildcard DNS for * pointing to your server.

Otherwise you need to create the appropriate A records you want to use.

Thanks for reading this post!

If you found an issue in this article, you can create an issue on Github.

If you have a comment or question, please drop me a line below!