Skip to content

Deploy an internal web app without a cloud subscription

A shared drive on your company network can host a real web application. How a PyInstaller executable plus a SQLite file on a file share became a deployment strategy, and when it is the wrong one.

  • python
  • automation
  • consulting
  • internal-tools

A long time ago I had to build a task management web application — the Jira or Trello shape, with a set of very specific requirements about how the data was handled locally. The application was not the problem. Deploying it was.

The company was a B2B consultancy with rigid procedures, and getting a budget approved for hosting a web application turned out to be close to impossible. No server, no cloud account, no line item for infrastructure. So the question became: what is the cheapest legitimate way to put a working web app in front of about thirty people who all sit on the same network?

The answer turned out to be a shared drive.

The setup

The application was written in Python, so most of the work was already done. I bundled it into a single Windows executable with PyInstaller, put a SQLite database file on the company file share, and pointed the executable at that path. Users copied the executable from the share to their own machine, double clicked it, and the app started.

From the user’s point of view there is no difference at all. It has a web interface, it persists data, several people use it at the same time, and nothing has to be paid for. That is the entire architecture.

The important detail is that the database lives on the share rather than beside the executable. Each person runs their own copy of the app, and all of those copies read and write the same SQLite file over the network. It is the least sophisticated deployment model I can describe, and it worked.

Why the network was the constraint

In a company that controls its own network, none of this is necessary. There is a server room, there is someone responsible for it, and the app goes on a box that somebody else already patches and backs up. That is the right answer and you should use it.

In my case the network was not ours. The company’s own people worked inside a client’s Citrix environment, on machines we did not administer and could not install software on. That eliminated every conventional option at once: no server, no container, no cloud VPC reachable from inside, no package manager on the desktop.

What was left was the file share, because that is the one thing everyone in the company could already reach. A shared drive is infrastructure that exists whether or not anyone planned to host an application on it.

The part everyone asks about

Copying the executable to a machine other than the one that built it triggers Windows SmartScreen and, more often, antivirus quarantine. Every time, for every user.

This is expected. Unsigned executables look exactly like malware, because malware is usually unsigned. Signing a desktop application requires a certificate from an authorised commercial authority, which costs money — the same money problem we were trying to avoid, just moved somewhere else.

There are three ways through it, in the order I would try them:

  • Add the executable to the antivirus exclusion list. One change, centrally managed, everyone stops seeing the warning.
  • Publish an internal PowerShell deployment script from the share that copies the file, adds the exclusion and runs it. Users get one double click and no dialog at all.
  • Install Python on the machines and ship a .bat file that runs the source code directly. No executable, no signature, no warning. The trade-off is that the source directory needs to be readable and the interpreter has to stay put.

None of these are security theatre. The application is not doing anything that antivirus is designed to catch, and the machine is inside a managed corporate network.

What this is actually good for

The pattern is not a general-purpose deployment strategy and I would not recommend it as one. It has a very specific shape of strengths:

  • A handful of named users on one network. Not thousands, not the public internet. People who already have access to the file share.
  • Data that is sensitive and must not leave the building. This is the strongest argument for it. The data never leaves the network, and there is no external processor to sign a DPA with.
  • No budget, no procurement, no IT ticket. If the decision would take three months and the app would still not be deployed, this is the correct answer even if it is not the elegant one.
  • A process that is genuinely bespoke. The value is that it fits exactly, and a commercial tool would need configuring into something it was not designed for anyway.

Where it falls apart

Being clear about this matters more than the enthusiasm.

Network file systems and SQLite are a known hazard. SQLite needs reliable locking to work correctly, and SMB does not always provide it. With low concurrency and human-paced writes — 200 people updating tasks during a working day — you will probably get away with it. With more, you are one bad week away from a corrupted database file. Back up that file, on a schedule, from a machine that is not a user.

It does not scale past a point. The ceiling is somewhere around “enough people to notice a file lock”, and it arrives when enough people use it intensely.

Deployment is manual. Everybody has to copy the new executable or source files on their PC.

It creates an expectation. If proceses change, the application will need updates. Not everyone knows coding. With excel you can get away with this.

It is not a security architecture. There is no authentication layer, no per-user permissions and no audit trail unless you build them. Treat the file share permissions as your access control and accept that they are coarse.

Where I would go now

If I were doing this again, the same reasoning points at Docker on a single internal VM, with Postgres in a container and a reverse proxy in front. It costs one machine, it is still entirely inside the network, and it gives you backups, migrations, logs and multiple users without any of the hazards above. It is not free, but it is a one-off if the hardware already exists.

The PyInstaller-plus-shared-drive approach is what you reach for when the constraint is not technical but organisational: no server, no budget, no control over the machines. It solved the problem I had, honestly and for the cost of an afternoon. I would just be honest with myself that it was a workaround for a procurement problem, and not pretend it is the way I would architect this today.

The real lesson

Almost every company has processes that software would remove and a budget process that will not pay for the software. The gap between those two facts is where most of the value I have found sits, and it is much wider than people assume. Tools like PyInstaller, SQLite and a file share have been free for long enough that “we cannot afford it” is frequently a statement about process, not about price.

If you have a process you suspect could be automated, or you genuinely do not know, tell me what it does today and what it costs you. I will tell you honestly whether it is worth building, whether something off-the-shelf already covers it, and what the cheapest possible version looks like in your environment. If the answer is “do not build anything”, that is a useful answer and I will say so.

Found a process worth automating?

Tell us about it. One email, no forms, no sales sequence.

contact@softgata.com

Keep reading