# stilleshan/frps: install scripts and a container image for the frp server

> This repository is not a tunneling tool of its own, it is packaging for the frp server from the fatedier/frp project, in the shape of a one command install script, an uninstall script, a systemd unit and a Docker image. The configuration file is left to you, and the image pins a specific frp release and downloads the matching binary at build time.

**stilleshan/frps** — 基于原版 frp 内网穿透服务端 frps 的一键安装卸载脚本和 docker 镜像.支持 Linux 服务器和 docker 等多种环境安装部署.

- Repository: https://github.com/stilleshan/frps
- Website: https://hub.docker.com/r/stilleshan/frps
- Stars: 878 · Forks: 370
- Language: Shell
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/stilleshan-frps

## A wrapper around the upstream frp server

The repository is described as a one command install and uninstall script and a Docker image built on the original frp intranet penetration server from the fatedier/frp project, supporting installation on Linux servers and in Docker and other environments. That distinction matters for how you judge it. Nothing here implements tunneling, the frp server itself is upstream, and what this repository adds is the plumbing: a script that fetches a release, a systemd service file, a configuration file and a container image. The Docker image is published on Docker Hub as stilleshan/frps, and the image supports both x86 and ARM. The primary language is Shell, the default branch is master, and the last push was on 2026-07-11. There are no GitHub releases, so the version you get is whatever the scripts and the image pin, which is the thing to check before you rely on either.

## The install script and the China mirror

The one command install fetches the script and runs it, and there is a second form of the same line that goes through a mirror, which is there because of network access rather than for any technical reason:

```bash
wget https://raw.githubusercontent.com/stilleshan/frps/master/frps_linux_install.sh && chmod +x frps_linux_install.sh && ./frps_linux_install.sh
```

The pattern is worth noting on its own terms. A remote script is downloaded with wget, made executable and run, all in one line, and the same is true of the mirror variant. That is convenient and it is also the case where you should read the script before running it, because a pipeline like this executes whatever the remote file contains at the moment you run it. The uninstall script follows the identical shape. The removal path is a wget of the uninstall script, a chmod and a run, with the mirror alternative underneath.

## The configuration is yours to edit, and then restart

The usage notes are explicit about the division of labour. Because the frp server needs configuration parameters, the script is based on the original frps.toml, and after installation you edit that file yourself to set the ports, the passwords and the other parameters, then restart the service. The commands for that are:

```bash
vi /usr/local/frp/frps.toml
sudo systemctl restart frps
```

So the workflow is install, edit, restart, and the script does not try to configure anything on your behalf. The documentation also notes the alternative route, which is to fork the repository, edit frps.toml and the install script yourself, and then run the one command install, which is convenient for a setup that differs from the default. The service commands are the standard systemd set, covering start, enable at boot, status, restart and stop:

```bash
sudo systemctl start frps
sudo systemctl enable frps
sudo systemctl status frps
sudo systemctl restart frps
sudo systemctl stop frps
```

The configuration file is at /usr/local/frp/frps.toml after the install, and the frps.service unit in the repository root is what the script installs to make the service manageable.

## Forking to pin your own version

The customisation route is documented as a sequence. You fork the repository, configure frps.toml, modify the frps_linux_install.sh script, modify the links in that script, and push to your own GitHub. Two variables in the script are the ones to change. FRP_VERSION is set to 0.70.0 and can be updated to a newer version following the upstream project, and REPO is set to stilleshan/frps, which has to be changed to your own GitHub account identifier because of the fork. The install link is then run with that account substituted, and the uninstall script is described as a general purpose script that can be run directly or modified the same way. The point of the fork route is control: you get to decide which frp version runs and what the configuration says, and the price is that you now own keeping that configuration in step with what the server actually needs.

## The Docker image pins one frp release at build time

The container image is where the version pin is visible. The Dockerfile starts from alpine 3.8 and sets a VERSION environment variable to 0.70.0 along with a time zone of Asia/Shanghai, installing the tzdata package and linking the zone information. The platform detection is a shell conditional over the machine architecture, mapping x86_64 to amd64, aarch64 to arm64 and the several 32-bit arm variants to arm. It then downloads the release tarball for that platform from the upstream GitHub releases, extracts it, moves the frps binary and the frps.toml into a /frp directory and removes the leftovers. The image declares /frp as a volume and its command is the server run against the configuration file inside it. The practical consequence is that the image is not tracking upstream, it is built around one specific release, so a newer frp version means rebuilding the image or overriding the version when you build it yourself.

## Running the container, and the configuration trap

The Docker instructions come with a warning that is worth repeating, because it is the failure mode people hit. To avoid the container failing to start and restarting in a loop because of a mistake in the format or the contents of the frps.toml file, the configuration has to be correct before you start the container. The steps are to clone the repository, edit frps.toml, and then run the container with the file mounted:

```bash
git clone https://github.com/stilleshan/frps
git clone https://ghfast.top/https://github.com/stilleshan/frps
vi /root/frps/frps.toml
```

The container itself runs detached, with a restart policy of always, on the host network, with the configuration file mounted into the server directory:

```bash
docker run -d --name=frps --restart=always \
    --network host \
    -v /root/frps/frps.toml:/frp/frps.toml  \
    stilleshan/frps
```

The note under that command says the mounted directory assumes the repository was cloned as described, and that you can create the frps.toml file anywhere and change the mount path instead. Changing the configuration on a running container means restarting it, which is the same edit and restart cycle as the script route.

## Conclusion

stilleshan/frps suits someone who wants the frp server running on a Linux box quickly, and who is comfortable editing a toml file and restarting a service afterwards, since that is the workflow the scripts set up rather than remove. It does not suit you if you want managed configuration or a supported product, because the scripts are a convenience wrapper and the configuration is yours to maintain. Before running the install script, read it, since it downloads and executes a remote file, and note that the container image pins frp 0.70.0, so you need to rebuild it to move to a newer release.

## FAQ

### What does stilleshan/frps actually provide?

It packages the frp server from the fatedier/frp project rather than implementing tunneling itself, in the form of a one command install script, an uninstall script, a systemd service file, an frps.toml configuration and a Docker image published as stilleshan/frps on Docker Hub, with support for both x86 and ARM.

### How do I install the frp server with this repository?

Run the one line command that downloads frps_linux_install.sh, makes it executable and runs it, with a variant of the same line going through a mirror for networks where GitHub is slow. After the install you edit frps.toml to set the ports, passwords and other parameters, then restart the service with sudo systemctl restart frps.

### How do I update to a newer frp version?

Fork the repository, change the FRP_VERSION variable in frps_linux_install.sh, which is set to 0.70.0, and change the REPO variable to your own GitHub account identifier, then run the modified script. The Docker image pins the same version at build time, so it needs rebuilding as well.

### Why does the Docker container keep restarting?

Usually because frps.toml is wrong. The instructions ask you to configure and check the file before starting the container, precisely so that a mistake in the format or contents of the configuration does not leave the container failing and restarting in a loop.

## Sources

- [Issues](https://github.com/stilleshan/frps/issues)
- [Project website](https://hub.docker.com/r/stilleshan/frps)
- [README](https://github.com/stilleshan/frps/blob/master/README.md)
- [stilleshan/frps on GitHub](https://github.com/stilleshan/frps)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stilleshan-frps
