Last week I ran into an interesting deployment challenge. Looking back, I thought it was worth documenting—not only as a personal note, but also as a case study that might help someone else in the future.
About two years ago, I built a website for a government organization. The previous system was written in Laravel 5.x, but for this project I decided to use WordPress instead. For a content-driven website like this, I didn’t see any reason to bring the entire Laravel framework into the project when WordPress could do the job perfectly well.
At that time, the original server backup was around 300 GB. After cleaning up duplicate files and removing unnecessary data, I managed to reduce it to only 7 GB. From there, I built a completely custom WordPress theme and prepared everything for deployment.
The First Deployments
The server was originally hosted by Viettel, so deployment was straightforward. They provided full root access, which meant I could install everything I needed and deploy the application without any restrictions.
Back then I hadn’t built Kumix.Cloud yet. If I had, the deployment process would have been even easier.
After migrating the system between VPS providers about five times, repeatedly setting up the same services became second nature, and honestly, a little boring. That’s when I decided to containerize the entire stack with Docker.
The idea was simple:
- Build once.
- Move the Docker stack to the new server.
- Start the containers.
Done.
I also considered using some popular server management panels, but I eventually decided against them. I never really know what they install on my servers, and whenever I need to customize something, I’m forced to depend on the panel itself. I prefer having full control over my infrastructure.
No More Direct SSH Access
Later, the organization migrated their infrastructure to another internal hosting environment.
The new virtual machine had more than enough CPU, RAM, and storage, but the way it was managed was completely different.
- No direct SSH access from the Internet.
- Access required connecting through Check Point Endpoint Security VPN.
- After connecting, I even had to modify my local hosts file to access internal domains.
Server management was done entirely through VMware® vSphere.
The VM console was extremely limited. There was almost no copy-and-paste support, and there wasn’t even a way to upload files directly.
At the time, I used the oldest trick in the book.
I uploaded a ZIP archive to another server, downloaded it inside the VM using wget, extracted it, and started my Docker containers.
It worked perfectly.
This Time Was Different
Some time later, the organization wanted a new data management system.
The new application would expose APIs for third-party integrations and allow staff to manage data daily without affecting the existing publishing workflow. The website would simply consume and display that data.
I built the application in Laravel and packaged everything with Docker, just like the existing system.
Last week, I decided to deploy it.
That’s when the real challenge began: wget no longer worked. I couldn’t even ping Google; in fact, I couldn’t access the Internet at all.
Apparently, after the first deployment, the organization had significantly tightened their security policies. The server was now almost completely isolated from the Internet, with only limited HTTP/HTTPS traffic allowed for the existing production services.
It was already midnight. It was the weekend.
I could have contacted the infrastructure team, but I chose not to. From experience, those kinds of requests often bounce between multiple departments and can easily delay a deployment until the following week.
So I decided to solve it myself.
Using the Existing Website as a File Transfer Tool
After thinking for a while, I tried something simple.
I uploaded a ZIP file through the WordPress Media Library.
Surprisingly, it worked.
The file wasn’t particularly large, so WordPress accepted it without any problems.
Combined with the terminal available through VMware, I could unzip the source code directly on the server.
Problem solved?
Not quite.
Docker introduced another obstacle.
Docker itself was already installed, but docker pull failed because the server couldn’t reach Docker Hub—or anywhere else on the Internet.
At that point, I asked AI a very simple question:
Can I export Docker images from one machine and restore them on another?
The answer was:
Absolutely.
So I exported all of the Docker images from my local environment, uploaded the archive files through the existing WordPress website, transferred them to the server, and imported them there.
This new application was deployed as a subfolder instead of a new domain, so I didn’t have to wait for anyone to configure DNS or virtual hosts.
About three hours later, everything was running successfully.
No help from the infrastructure team.
No Internet access.
No security policy changes.
What I Learned
Some problems look impossible at first.
No Internet.
No direct SSH.
No wget.
No docker pull.
It feels like there’s simply no way to deploy.
But once I slowed down, analyzed the problem step by step, made use of everything that was already available, and let AI help me explore alternative approaches, the solution gradually became clear.
In hindsight, Docker turned out to be one of the biggest advantages.
If I needed additional services—Redis, for example—I didn’t have to install anything from the Internet. I simply exported the Docker image from my machine, uploaded it through the existing WordPress site, restored it on the server, and started the container.
Sometimes the solution is already there, you just have to look at the problem from a different angle.
TL;DR
- Deployed a web application to a government-managed server.
- The first deployment succeeded because the security restrictions were still relatively relaxed.
- During the second deployment, the server was almost completely isolated from the Internet: no ping, no
wget, nodocker pull. - Used the existing WordPress website to upload both the application source code and Docker image archives.
- Exported and imported Docker images instead of pulling them from Docker Hub.
- Successfully deployed the new application in about three hours without involving the infrastructure team.
This wasn’t the hardest deployment I’ve ever done, but it reminded me of something important:
Many problems aren’t as difficult as they first appear. Sometimes, all you need is a different approach, a bit of curiosity, and the willingness to experiment.