Automatically deploy FRP server and client services using Docker

Automatically deploy fast reverse proxy server and client services using Docker.png
Automatically deploy fast reverse proxy server and client services using Docker.png

It is an easy way to de­ploy FRP server and client ser­vices us­ing Docker, which sim­pli­fies the setup process by break­ing it down into four parts.

Breakdown of content
Part1, Menu Settings
function display_menu {
    echo "Please select a service as you want to deploy:"
    echo "1. FRP(S) Service"
    echo "2. FRP(C) Service"
    echo "0. Exit"
}

2023-03-21_120127.png
2023-03-21_120127.png

The script starts with a menu that pre­sents the user with three op­tions to choose from. This menu is es­sen­tial to guide the user through the rest of the process.


Part2, FRP Server service deploy
function handle_option_1 {
}

This part sets up the FRP server ser­vice as a func­tion.

in­clude the fol­low­ing
if ! command -v docker &> /dev/null
then
    echo "Docker is not installed. Installing Docker now..."
    curl -O https://kingtam.win/usr/uploads/script/install-docker.sh && chmod +x install-docker.sh && ./install-docker.sh
fi

It de­tects if Docker is in­stalled and if not, in­stalls it.

echo "What port would you like to use for the frps service? Press enter to use the default port of 7000, type 'r' to generate a random port, or enter a port number:"
read -r port_choice

if [[ $port_choice == "r" ]]; then
    port=$(shuf -i 7001-9000 -n 1)
elif [[ -z $port_choice ]]; then
    port=7000
else
    port=$port_choice
fi
echo "What port would you like to use for the HTTP service? Press enter to use the default port of 80, or enter a port number:"
read -r http_choice

if [[ -z $http_choice ]]; then
    http=80
else
    http=$http_choice
fi
echo "What port would you like to use for the HTTPS service? Press enter to use the default port of 443, or enter a port number:"
read -r https_choice

if [[ -z $https_choice ]]; then
    https=443
else
    https=$https_choice
fi
echo "Would you like to generate a random token or enter a password for the frps service? Press enter to generate a random token, or enter a password:"
read -r token_choice

if [[ -z $token_choice ]]; then
    token=$(openssl rand -hex 16)
else
    token=$token_choice
fi

Then it prompts the user to cre­ate the FRP server ser­vice, HTTP, HTTPS, and to­ken.

if [ ! -d "./frps/tmp" ]; then
    mkdir -p "./frps/tmp"
else
    sudo rm -rf "./frps" && mkdir -p "./frps/tmp"
fi

It also checks if the folder ./​frps/​tmp ex­ists and cre­ates it if it does­n't.

cat >> "./frps/frps.ini" << EOF
[common]
bind_addr = 0.0.0.0
bind_port = $port
vhost_http_port = $http
vhost_https_port = $https
dashboard_tls_mode = false
enable_prometheus = true
log_file = /tmp/frps.log
log_level = info
log_max_days = 3
disable_log_color = false
detailed_errors_to_client = true
authentication_method = token
authenticate_heartbeats = false
authenticate_new_work_conns = false
token = $token
max_pool_count = 5
max_ports_per_client = 0
tls_only = false
EOF

cat >> "./frps/docker-compose.yml" << EOF
version: '3'
services:
    frps:
        image: snowdreamtech/frps:latest
        container_name: frps
        network_mode: "host"
        restart: always
        volumes:
            - "$PWD/frps/frps.ini:/etc/frp/frps.ini"
            - "$PWD/frps/tmp:/tmp:rw"
EOF

docker-compose -f "./frps/docker-compose.yml" up -d

sleep 3
sudo cat "./frps/tmp/frps.log"

echo -e "\033[1;32mServer IP Address:\033[0m $(curl -s ifconfig.co)"
echo -e "\033[1;32mService Port:\033[0m $port"
echo -e "\033[1;32mToken:\033[0m $token"
echo -e "\033[1;32mHTTP Port:\033[0m $http"
echo -e "\033[1;32mHTTPS Port:\033[0m $https"

Fi­nally, it cre­ates the FRP server con­fig file, docker-com­pose.yml file, starts up the docker-com­pose, and prints the frps.log with in­for­ma­tion in color.

2023-03-21_120218.png
2023-03-21_120218.png


Part3, FRP Client service deploy
function handle_option_2 {
}

This part sets up the FRP client ser­vice as a func­tion.

in­clude the fol­low­ing
if ! command -v docker &> /dev/null
then
    echo "Docker is not installed. Installing Docker now..."
    curl -O https://kingtam.win/usr/uploads/script/install-docker.sh && chmod +x install-docker.sh && ./install-docker.sh
fi

It also de­tects if Docker is in­stalled and in­stalls it if it is­n't.

read -p "Enter the FRP(S) Server ip address or domain: " frpsip
read -p "Enter the FRP(S) Service port (press Enter for default **7000** or manual to input a port): " port
if [ -z "$port" ]
then
    port=7000
else
    read -p "Enter the FRP(S) Service port: " port
fi

read -p "Enter the FRP(S) Service token: " token

read -p "Enter the port of FRP(C) admin console (press Enter for default **7400** or manual to input a port): " cport
if [ -z "$cport" ]
then
    cport=7400
else
    read -p "Enter the FRP(C) admin console port: " cport
fi

read -p "Enter the username of FRP(C) console (press Enter for default **admin** or manual to input a name): " cname
if [ -z "$cname" ]
then
    cname=admin
else
    read -p "Enter the username of FRP(C) console: " cname
fi

echo "Would you like to generate a Random Console Password (Press Enter) or enter a password for the FRP(C) console?"
read cpasswd

if [[ -z $cpasswd ]]; then
    ctoken=$(openssl rand -hex 12)
else
    ctoken=$cpasswd
fi

Then the user is prompted to cre­ate the FRP client ser­vice, FRP server IP ad­dress or do­main, port, to­ken, ad­min ad­dress, con­sole, and con­sole to­ken.

if [ ! -d "./frpc/tmp" ]; then
    mkdir -p ./frpc/tmp
else
    sudo rm -rf ./frpc && mkdir -p ./frpc/tmp
fi

It also checks if the folder ./​frpc/​tmp ex­ists and cre­ates it if it does­n't.

cat >> frpc/frpc.ini << EOF
[common]
server_addr = $frpsip
server_port = $port
token = $token
log_file = /tmp/frpc.log
log_level = info
log_max_days = 3
disable_log_color = false
admin_addr = 0.0.0.0
admin_port = $cport
admin_user = $cname
admin_pwd = $ctoken
EOF

cat >> frpc/docker-compose.yml << EOF
version: '3'
services:
    frpc:
        image: snowdreamtech/frpc:latest
        container_name: frpc
        network_mode: "host"
        restart: always
        volumes:
            - ./frpc.ini:/etc/frp/frpc.ini
            - ./tmp:/tmp:rw
EOF

docker-compose -f ./frpc/docker-compose.yml up -d

sleep 3
sudo cat ./frpc/tmp/frpc.log

echo -e "Please use below information to Login console and setup your FRP(C) services"
echo -e "The address of console: \033[1;32mhttp://localhost:$cport\033[0m"
echo -e "The username of console: \033[1;32m$cname\033[0m"
echo -e "The password of console: \033[1;32m$ctoken\033[0m"

Fi­nally, it cre­ates the FRP client con­fig file, docker-com­pose.yml file, starts up the docker-com­pose, and prints the frpc.log with in­for­ma­tion in color.

2023-03-21_120312.png
2023-03-21_120312.png


Part4, Use case statement
display_menu

read -p "Enter your choice [0-2]: " choice

case $choice in
    1)
        handle_option_1
        ;;
    2)
        handle_option_2
        ;;
    0)
        echo "Exiting..."
        exit 0
        ;;
    *)
        echo "Invalid choice"
        ;;
esac

The case state­ment that eval­u­ates the value of $choice and ex­e­cutes the cor­re­spond­ing code block. If the user en­ters a value that is not one of the three op­tions, the * case matches and an er­ror mes­sage is dis­played.


Use The Script:
  • Save the contents of the script in a file, e.g., frp.sh.
  • Make the script executable with chmod +x frp.sh.
  • Run the script as root or with sudo: sudo ./frp.sh.

Also, We can us­ing a sin­gle com­mand line in the ter­mi­nal. (Root Priv­i­leges is re­quires)

curl -O https://kingtam.win/usr/uploads/script/frp.sh && chmod +x frp.sh && ./frp.sh

This com­mand will down­load the script from URL, make it ex­e­cutable, and then run it. If any of the com­mands fail, the sub­se­quent com­mands will not be ex­e­cuted.


Conclusion:
This bash script sim­pli­fies the de­ploy­ment of FRP server and client ser­vices us­ing Docker. Its four parts guide the user through the setup process, mak­ing it easy to cre­ate and run the ser­vices. By break­ing down the process into man­age­able parts, this script re­duces the com­plex­ity of the setup process for users.

Related: