Operations 13 min read

Automated Environment Deployment Using FRP, Ansible, and Docker

This article describes a three-stage automated deployment strategy—traditional installation, VM image restoration, and automatic discovery with command issuance—leveraging FRP for internal network tunneling, Ansible for batch control, and Docker for rapid containerized deployment, significantly reducing operational effort and enabling a DevOps workflow.

Java Captain
Java Captain
Java Captain
Automated Environment Deployment Using FRP, Ansible, and Docker

Preface

We have gone through three phases of environment deployment: traditional installation, VM image restoration, and automatic discovery with command issuance. After restoring a VM image, the machine registers automatically once it can ping our company address, giving us management control without opening external ports.

Background

Our company delivers customized products that are deployed directly onto client servers. Clients usually provide 1‑2 virtual machines in their own data centers, leaving the entire environment setup to us.

Phase 1: Traditional Installation

Timeframe: up to 2016.

Clients must provide remote access methods (bastion host, VPN, direct ports, etc.), which vary case by case.

Manually upload database, JDK, Tomcat packages (slow due to bandwidth).

Install database, JDK, Tomcat, Nginx (Linux scripts still time‑consuming).

Manually deploy WAR packages.

This approach required 3‑5 person‑days per deployment and was error‑prone due to inconsistent disk layouts and software versions.

Phase 2: VM Image Restoration

Timeframe: 2016‑2017.

Clients still provide remote access methods.

Restore a prepared VM image (including Docker) and set the IP.

Deploy WAR packages with a one‑click deploy module.

We packaged steps 2‑5 of Phase 1 into a VM image and built the deploy module, making the system stateless. Deployment time dropped to 2‑6 hours, and we entered a DevOps era without a dedicated ops person.

Phase 3: Automatic Discovery & Command Issuance

Timeframe: 2017‑2018.

Clients restore our VM image and ensure it can ping our address.

The machine automatically registers and receives commands.

The deploy module deploys WAR packages with a single click.

Deployment now takes 5‑10 minutes, no remote access from the client is needed, and we can batch‑manage all machines, laying the groundwork for future scaling.

Specific Technologies

The following sections focus on Phases 2 and 3.

FRP (Fast Reverse Proxy)

FRP is an internal‑network tunneling tool that can expose a machine without a public IP to another internal network.

Installing the FRP Server

Choose an internal machine (e.g., 172.0.0.2) that has a fixed public‑IP route.

wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-install-shell/master/frps/install-frps.sh -O ./install-frps.sh
chmod 700 ./install-frps.sh
./install-frps.sh install

All parameters have defaults; just press Enter.

Please input frps bind_port [1-65535](Default Server Port: 5443): # default
Please input frps vhost_http_port [1-65535](Default vhost_http_port: 80): # optional
Please input frps vhost_https_port [1-65535](Default vhost_https_port: 443): # optional
Please input dashboard_port [1-65535](Default dashboard_port: 6443): # default
Please input dashboard_user (Default: admin): # default
Please input dashboard_pwd (Default: kpkpM7VZ): # change if desired
Please input privilege_token (Default: 9m2UAOWa6hx5Eise): # default
Please input frps max_pool_count [1-200](Default max_pool_count: 50): # default
1: info
2: warn
3: error
4: debug
Enter your choice (1, 2, 3, 4 or exit. default [1]): 1
...

After this, the FRP server is ready.

Client Setup (Linux Example)

Download the client package from http://diannaobos.iok.la:81/frp/frp-v0.14.0/ , extract it to ~/frp , and keep the frpc binaries.

Registration Script (reg.sh)

Place the following script in ~/reg.sh (also in ~/ ):

UUID=$(cat /sys/class/dmi/id/product_uuid)
wget -O frpc.ini http://114.114.114.114/frp.php?file=$UUID;
a=`du -s frpc.ini | awk '{print $1}'`
if [ $a -lt 1 ]
then
    echo "none"
else
    echo "action"
    pkill frpc
    sleep 2s
    rm -rf ~/frp/frpc.ini
    cp frpc.ini ~/frp/frpc.ini
    ~/frp/./frp.sh
fi

The UUID uniquely identifies the server; the script fetches a generated frpc.ini from the central registration server (IP 114.114.114.114).

Cron Job

crontab -e
*/5 * * * * ~/reg.sh

This runs the registration script every five minutes, pulling updates only when the server configuration changes.

FRP Auto‑Start on Linux

chmod +x ~/frp/frp.sh
vi /etc/rc.d/rc.local   # add at the end:
bash ~/frp/frp.sh
chmod +x /etc/rc.d/rc.local

Simple Registration Server (frp.php)

<?php
$filename=$_GET['file'].'.ini';
$filename='frp/'.$filename;
if(!file_exists($filename)){
    file_put_contents($filename, "");
    file_put_contents($filename.'.update', $_SERVER['REMOTE_ADDR']);
}else{
    if(!file_exists($filename.'.update')){
        $str = file_get_contents($filename);
        echo $str;
        file_put_contents($filename.'.update', $_SERVER['REMOTE_ADDR']);
    }
}
?>

When a machine registers, a file named after its UUID appears in the frp directory. Updating the .ini file and removing the .update triggers the server to reload the configuration.

Example .ini Configuration

[common]
server_addr = 114.114.114.114
server_port = 5443
privilege_token =
[webserver]
type = tcp
local_ip = 127.0.0.1
local_port = 22
use_encryption = false
use_compression = false
remote_port = 7001

[a-web]
type = http
local_ip = 127.0.0.1
local_port = 80
use_encryption = false
use_compression = true
custom_domains = a.a.com

This configuration tunnels the local SSH port (22) to remote port 7001 and exposes the local HTTP service on a.a.com .

Ansible

Ansible is used for batch control of the registered machines. (Reference: https://juejin.im/post/59decdb9518825422c0ca44c)

Docker

Docker containers are employed for rapid system deployment, enabling consistent environments across machines.

Portainer

Portainer provides a UI for managing Docker containers. (Reference: https://juejin.im/post/596587a56fb9a06baa63d435)

Deploy Tool

Our custom deploy tool orchestrates version control and deployment. (Reference: https://juejin.im/post/59633a126fb9a06ba024ffdd)

Conclusion

This article demonstrates how to use FRP for internal network tunneling, Ansible for batch operations, Docker for fast containerized deployment, and a custom deploy system for version management, dramatically reducing operational costs and enabling a small company to operate in a DevOps model without dedicated ops staff.

DockerautomationDeploymentDevOpsAnsiblefrp
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.