Operations 13 min read

How We Cut Deployment Time from Days to Minutes with FRP, Docker, and Ansible

This article details a three‑stage evolution of environment deployment—from manual installation to VM image restoration and finally to automatic registration with command issuance—showing how FRP tunneling, Docker containers, Ansible automation, and a custom deploy tool dramatically reduce deployment effort and eliminate the need for dedicated ops staff.

Programmer DD
Programmer DD
Programmer DD
How We Cut Deployment Time from Days to Minutes with FRP, Docker, and Ansible

Preface

We have gone through three stages in solving environment deployment problems: traditional installation, image restoration, and automatic discovery registration with command issuance. After image restoration, once a VM can ping our company address it automatically registers, giving us management rights and enabling batch command distribution.

Background

We are a product‑plus‑custom‑requirements company. After a project is completed we deploy directly to the client’s servers. Clients usually provide 1‑2 virtual machines in their own data center, leaving the entire environment setup to us.

Evolution

Stage 1: Traditional Installation (≈2016)

Clients provide various remote‑access methods (bastion host, VPN, direct ports, etc.).

Remote into the server.

Upload database, JDK, Tomcat packages (often slow due to bandwidth).

Install the database.

Install JDK, Tomcat, Nginx (run prepared shell scripts on Linux, still time‑consuming).

Manually deploy WAR packages and other artifacts.

This method is cumbersome, often requiring 3‑5 person‑days, which is impractical for a team with only one ops engineer.

Stage 2: Image Restoration (2016‑2017)

Clients still provide remote‑access methods.

Restore a VM from a prepared image (including Docker).

Deploy WAR packages with a one‑click deploy module.

We packaged steps 2‑5 of Stage 1 into a VM image, built a deploy module, and made the project stateless. Ops dependence dropped dramatically, reducing work to 2‑6 hours.

Stage 3: Automatic Discovery Registration + Command Issuance (2017‑2018)

Clients restore our VM image, set the IP, and ensure it can ping our company address.

Automatic discovery registration and command issuance.

One‑click WAR deployment via the deploy module.

Deployment time fell to 5‑10 minutes, we no longer needed client‑side remote access, and we could batch‑manage all machines, laying the groundwork for future scaling.

Specific Technologies (Stages 2 & 3)

FRP

FRP is an internal‑network‑penetration tool. We use it to expose a machine without a public IP to another internal network.

Installing the FRP Server

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 accept defaults.

Installing the FRP Client (Linux example)

Download frp_0.14.0_linux_amd64.tar.gz, keep the files prefixed with frpc, and extract them to ~/frp.

reg.sh Script

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, ensuring even identical VM images have distinct identifiers. The IP 114.114.114.114 is our external registration server.

crontab

*/5 * * * * ~/reg.sh

The script runs every five minutes to register or fetch changes; if the server configuration is unchanged, the service does not restart.

FRP Auto‑Start (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 frp.php Backend

<?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']);
    }
}
?>

.ini Example

[common]
server_addr = 114.114.114.114
server_port = 5443
privilege_token = <strong>secret</strong>

[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

With this configuration the internal machine’s port 22 is tunneled to 172.0.0.2:7001, and its HTTP service is reachable via a.a.com.

Ansible

Ansible is used for automated batch control; see the separate article “Practical Ansible for Automated Operations”.

External Port Mapping

Map external IP 114.114.114.114:5443 to internal 172.0.0.2:5443 while leaving other ports untouched.

Docker

Docker images enable rapid deployment of our system; see the related blog post on DevOps transformation.

Portainer

Portainer provides a web UI for Docker management; see the comparison article for alternatives.

Deploy Module

Our custom deploy tool handles automatic WAR upgrades; refer to the “Java Web Project WAR Auto‑Upgrade Solution” article for details.

Conclusion

By combining FRP tunneling, Ansible batch control, Docker rapid deployment, and a custom deploy system, we dramatically reduced operational costs and entered a DevOps era without dedicated ops personnel. This approach can help other small companies facing similar deployment challenges.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

automationDeploymentDevOpsAnsiblefrp
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

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.