If you're deploying software on a closed network, you might want to read this post
Who still deploys software via USB these days? ???: Hello? I'm that very "someone."
Who still deploys software via USB these days? ???: Hello? I'm that very "someone."
These days, container deployment and CI/CD automation are standard practice when operating web applications. It’s now taken for granted that a complex deployment workflow can be completed in a relatively short time the moment code is merged into the main branch.
But is this even possible when deploying to a location without an internet connection—that is, a “closed network”?
The term “closed network” here does not simply refer to a corporate intranet. It refers to an independent network environment that is completely isolated from the outside world, where even the deployment pipeline set up within the company is inaccessible. Since we live in such a connected world, a closed network may feel like a rather unique scenario.
A disconnected network also means that we cannot use some of the automated pipelines and deployment strategies we’ve come to rely on. Deploying in a completely isolated environment requires following much more detailed steps than one might expect.
This article was written to help those who have knowledge and experience with containers and deployment processes for web applications but are deploying to a closed network for the first time.
I have experience deploying to a hospital’s closed network. The hospital was a “customer” using our service, and we had to deploy the application on a per-hospital-site basis.
Of course, there are hospitals that actively adopt cloud solutions, but since security regulations vary from hospital to hospital, there were quite a few instances where we were asked to perform on-premises deployments on servers with no internet connection. In cases where even a VPN connection was unavailable, I had to physically visit the hospital to perform the deployment. It was an experience that made me keenly realize that deployments on completely isolated networks are, surprisingly, a real possibility. (And, very importantly, a USB drive is essential. Make sure to always carry one.)
This isn’t limited to hospital domains alone. Any organization with strict security policies may request application deployment on a closed network.
You must verify the specifications of the provided server. Be sure to check the following three items:
However, based on my experience as a junior developer, I’ve found that sometimes it’s impossible to install Docker using just the binary file. In one instance, the provided Ubuntu machine was so “pure” that I had to install additional apt packages. Installing apt packages is easy only if you have internet access. If you need to install additional packages on a closed network, you may face the ordeal of having to find and transfer each package binary file one by one. While it’s sometimes possible to explain the situation and request temporary internet access, there are always cases where this is prohibited by the client’s policies.
Of course, the process doesn’t end with installation. On an Ubuntu machine, whether using the binary or apt, proper installation usually requires almost no additional configuration; however, on a Windows machine, you’ll also need to configure WSL and other settings. It’s bound to become more and more of a headache.
Since all packages used in the project can be installed in an environment with internet access, build the image in advance in a location with an open internet connection.
dockerFROM python:3.11-slim WORKDIR /app COPY requirements.txt . # 파이썬의 pip 패키지 설치도 마찬가지로 인터넷 가능한 환경에서 빌드해야 함 RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Also, you must build the image on a Linux/amd64 platform. (For example, build it on a Linux server at your company). Even if you can build the image on your local computer, you should think twice if you’re using a MacBook. Building in a macOS environment changes the Docker image’s platform information, which may prevent it from loading at all in a hospital environment (Windows computers).
To deploy to a closed network, you need to consider the local computer, the server for building the image, and the actions required on the closed network server. Until now, closed network deployments have typically followed the procedure below.
렌더링 중...
렌더링 중...
docker save -o target_image_file_name.tar target_image_namedocker load -i target_image_file_name.tarIf you have set up an in-house CI/CD pipeline to upload tar files to cloud storage or similar services, you can follow the sequence diagram below.
렌더링 중...
It’s a good idea to plan your strategy for managing tar files, images, and environment variables on closed-network servers in advance.
Otherwise, you might accidentally overwrite existing files or lose files you need, forcing you to transfer them back and forth via USB multiple times—which can be quite a hassle.
Let’s think about how we handle version control when deploying via CI/CD and consider how we can apply those principles to an on-premises environment. (This might feel like a very old-school approach, but ultimately, good folder management might be the best solution. It would be a relief if we even had a local registry…)
It’s absolutely essential to document all tasks and troubleshooting processes involved in deploying to a closed network.
Even if you do your best to minimize the gap between local and in-house development environments and the closed network environment by requesting proper environment setup well in advance, unexpected problems can still arise.
It’s never easy to make an external server 100% match the environment of an on-premises server. This is only natural, since you or your company isn’t in charge of managing the external server. Therefore, aiming for a perfect deployment on the first try can end up causing you more stress.
Diagnose and document any issues that arise. You need to determine whether the problem lies with the server specifications, the server software, the Docker configuration, or the application code so that you can take proactive measures for the next on-premises deployment.
Don’t forget that the two points mentioned above are ultimately for the benefit of your future self and others.
When working on various projects, it’s inevitable that project leads will change or roles and responsibilities (R&R) will shift under certain circumstances. In such situations, it’s crucial to align everyone’s understanding of the context as much as possible. If this alignment is off, bottlenecks in work are bound to occur even within the company—and if the status of external networks isn’t even clarified, everyone could suffer.
Therefore, be sure to meticulously maintain documentation of deployment status and troubleshooting records for each client. You can contribute to the team’s harmony.
(Note) A handy tip for making a quick escape (?) from an off-site location when an issue arises at the application level after deployment
If an error occurs during deployment or production testing and debugging requires a code-level fix, or if an immediate update and response are needed,(e.g., when data that was difficult to verify on the development machine is confirmed on a production machine in a closed network, and the query doesn’t work as expected—there have been cases where this could be addressed via ORM), you can use the following method.
plain1. docker exec -it container_name bash로 컨테이너 내부 소스 코드에 접근 2. vim으로 수정할 코드를 직접 수정 후 저장(이미지 빌드 시 vim을 설치 하지 않았다면 vi로 코드 수정) 3. exit로 컨테이너 환경 탈출 4. docker commit container_name image_name:tag 로 변경된 코드를 이미지에 커밋 -> 이미지 해시가 변경되며 이미지 형상이 바뀜 5. docker rm container_name && docker run {{필요한 옵션들}}로 컨테이너 재실행(docker-compose 사용시 docker compose up으로 재실행) ``` However, **this is not recommended**. This is because it breaks the deployment image you’ve been managing. While it’s a viable option if you’re solely focused on a “quick fix,” if you do use this method, be sure to modify the code immediately upon returning to the office and replace the deployment image during your next visit. ## In Conclusion Deploying to a closed network may feel like something you have to put up with because you’ve grown accustomed to the convenience of automated systems. I, too, have had that thought. Still, if you shift your perspective, the step-by-step process for deployment isn’t significantly different, whether you use an automated pipeline or deploy directly to a closed network. The only difference is that the nature of the work at each step and the technologies used have changed, and tasks that were once done by people are now handled by computers. If you view this as a path to mastering each step firsthand, you’ll become a powerhouse—and I came to see that as the path to peace of mind. The most challenging part of deploying to a closed network was having to **endlessly repeat the process of building images and transferring them via USB**. With a modern CI/CD workflow in place, you can redeploy with a single click of a button, but in a closed network, a human has to do this manually. Perhaps I was trying to “evolve” (?) in a direction that would minimize my own suffering. This post alone cannot cover every possible scenario for closed-network deployments. This is because there are so many different deployment environments, and communication methods, stakeholder relationships, and workflows vary widely from organization to organization. Therefore, I hope this article will guide you on the most fundamental considerations when performing closed-network deployments, thereby reducing the number of variables you need to worry about. I also hope that using these guidelines will make it a little easier to respond appropriately to different situations. (Good luck to everyone handling closed-network deployments!)