- Published on
Just Get It Working
- Authors

- Name
- Mamun Rashid
It is Tuesday. The founder, Dana, drops a zip file into the team chat. Inside is a Go service a contractor wrote, a README with three environment variables, and a note that says the binary "should just run." There is a pilot customer demo on Friday.
"Can you just get it online?"
If you have worked at a startup, you have heard some version of that sentence. It is not a request for architecture. Nobody wants to hear about orchestrators, service meshes or a five-environment promotion pipeline. The business wants users, features and a link that works on Friday. That is the correct priority, and the sooner you accept it the better your decisions get.
This post walks through that week. Four decisions, each made for a specific reason, and each one handing a problem to someone else on purpose.
What you are actually holding
You did not write this code and you will not be rewriting it. You know it reads DATABASE_URL, PORT and an API key, and you know it starts. That is the whole contract.
This is more common than people admit. A lot of platform work is keeping software running that you only understand from the outside. So the constraints write themselves:
- The fastest path to production with the least ongoing effort. Nobody is hiring a second person for this.
- The biggest win for the smallest setup.
- No optimizing. You do not know yet what needs maintaining, so you cannot know what to optimize.
On Tuesday evening the whiteboard has four boxes on it: somewhere to keep the code, somewhere for the app to run, somewhere for the data to live, and somewhere for the secrets to go. Everything below is filling in those boxes.
Wednesday morning: a server or a container?
The first instinct is to rent a server. A VPS is just an instance: SSH in, install Go, copy the binary over, start it under a process manager, done. It works. A large share of the web still runs exactly like that, and plenty of businesses never leave it.
The case for a container is not that it is better on Friday. It is that it is the shape you will want in a year. An image is a portable copy of the whole environment, so moving to a bigger platform later becomes a change of runtime, not a rewrite of how you deploy. One small decision now keeps a large door open.
| Option | Good at | Costs you |
|---|---|---|
| VPS | Dedicated CPU and memory. Best for sustained heavy compute, where you would be a noisy neighbour on shared hardware. | You own the OS, the patching, the restarts and the scaling. |
| Managed PaaS | Hand over source code and get a running app back. | The provider builds the artifact for you, so it is less yours to move. |
| Container on a managed runner | You own the image and the provider owns everything under it. Autoscaling and restarts come built in. | You learn Docker now, and you trust a box you cannot see inside. |
A small Go service talking to a database is not short on CPU. It is short on time. Portability wins, so it goes in a container.
Wednesday midday: where the container runs
Every cloud provider sells an entry-level service designed to get you in the door. On AWS that is App Runner: point it at an image and it runs it, with HTTPS, horizontal scaling and automatic restarts included. Underneath it is AWS's existing container infrastructure with a much smaller surface on top.
The image needs a home first, so it goes into ECR, Amazon's container registry. The whole flow is three steps: build the image, push it to the registry, and tell App Runner to pull it.
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin "$REGISTRY"
docker build -t "$REGISTRY/app:latest" .
docker push "$REGISTRY/app:latest"
aws apprunner start-deployment --service-arn "$SERVICE_ARN"
Two things follow from this choice, and both are worth saying out loud.
First, you might never need to leave. Autoscaling used to be a keynote demo. Now it is a default on the cheapest tier. If the entry service keeps up with your growth, Kubernetes is a cost with no matching benefit.
Second, lock-in is really a question of ownership. App Runner or ECS, it is the same provider underneath. The real decision is how much of the stack you want to own, not which logo is on the invoice.
Wednesday afternoon: who looks after the data?
This is the box where people get ambitious. Should you spin up your own Postgres instance? Configure RDS, its subnets, its security groups, its parameter groups, its backup windows?
Ask a different question: who on this team is the database administrator? Large companies hire a DBA because a busy production database is a full-time job. Backups, retention, failover, upgrades, connection limits, the migration that locks a table at 2pm. If nobody on the team is going to do that job, then the goal is to make the database as small a problem as possible.
So you outsource it. A managed Postgres provider such as Supabase gives you a database and a connection string in a few clicks. It handles backups, connection pooling and uptime. It also gives you a public endpoint, which sounds alarming and is the reason it is fast: no VPC, no peering, no firewall rules to get wrong on a Wednesday. Use TLS, use a long generated password, restrict access by IP if the provider supports it, and move on.
Will you stay there forever? Probably not. Managed databases get expensive as you grow, because that is how they make their money. But this early, the bigger risk is spending the week on infrastructure instead of the product. And if the company is not making money yet, lean hard on free tiers. Every major provider has one, and a database bill before your first paying customer is a bill you did not need.
Thursday: where do the secrets go?
The database password exists now, and so does the API key. The tempting move is to paste them into the service's environment variables in the console and call it done. That works, but it scatters secrets across consoles and shell history, with no record of who changed what.
The middle ground is AWS Systems Manager Parameter Store. It is a key-value store with encryption, a console you can click through, and nothing to deploy or run yourself. App Runner can read values from it directly and hand them to the app as environment variables, so the image never contains a secret.
The obvious follow-up is "why not Secrets Manager?" Both encrypt with KMS and both work. The difference is shape:
- Parameter Store is one value per key:
/app/prod/database-url,/app/prod/api-key. It suits lookups of one value at a time, and its standard tier costs nothing. - Secrets Manager stores a document per secret, which can hold many values and be fetched in a single call. It adds automatic rotation, and it charges per secret per month.
For four values and one service, Parameter Store is plenty. When you have dozens of services and want rotation, revisit it.
Thursday night: everything is manual, on purpose
Here is what the week built.
Look at the green arrows. Pushing the image, running the schema migration, changing a config value, triggering a deploy: every one of them is a person at a terminal. There is no pipeline, no infrastructure as code, no preview environments.
That is not a gap. Automation costs time to build and time to maintain, and right now you do not know which of those arrows you will run fifty times and which you will run twice. Run them by hand, notice which ones hurt, and automate those first.
Friday: the demo works
The link loads. The customer clicks around. Dana is happy. And from the customer's side, a request goes to App Runner and an answer comes back.
Is there a CDN in front of it? Is anything cached? How exactly does a new deploy swap traffic over? You do not know, and you chose not to know. That is the trade you made on Wednesday, and it is a good one, as long as you remember you made it.
I run a product on almost exactly this shape: an image in ECR, App Runner pulling it, a managed database. The thing that bit us was not performance. A deploy failed its health checks and App Runner quietly rolled back to the previous image. The pipeline was green. The site was old. Deploys also queue one at a time, so two changes shipped close together land minutes apart.
A green build tells you an image exists, not that it is live. Check the service's own deployment history, then check the behaviour in a browser.
That is the general shape of the cost. When one service owns scaling, routing, restarts and rollbacks, it also owns the failure modes of all four, and its defaults decide what you hear about. Learn its signals early: where it logs, what a rollback looks like, how you confirm a deploy actually landed.
The conversation that matters more than the YAML
The following Monday, Dana forwards a message from an advisor: "Shouldn't you be on Kubernetes?"
There are two ways to answer. One is a list of options with pros and cons. The other is a decision with a reason the business can weigh: "We are on a managed runner because it scales on its own and nobody here has to operate a cluster. We will revisit it when the bill or a feature forces us to, and moving will be cheap because we chose containers."
The further you go in DevOps and platform work, the less the job is the technology and the more it is that second kind of answer. Engineers who make suggestions get asked for options. Engineers who make decisions get asked to own the platform.
What to carry forward
- The first phase optimizes for shipping and learning. Don't optimize what you don't understand yet.
- Fill four boxes: code, app, data, secrets. Nothing else is required to launch.
- Pick containers early if you expect to grow. It is cheap now and expensive later.
- Use the provider's simplest managed runner and its registry. You may never outgrow them.
- If nobody on the team is a DBA, rent one in the form of a managed database. Use free tiers until revenue says otherwise.
- Keep secrets out of the image and out of pasted environment variables. A managed key-value store is enough to start.
- Manual is fine. Automate the steps that hurt, once you know which ones they are.
- Every abstraction hides failure modes. Learn how yours reports a failed or rolled-back deploy before you need to.
- Answer in business terms, and make the call.
Enjoyed this post?
Subscribe to get notified about new posts and updates. No spam, unsubscribe anytime.
By subscribing, you agree to our Privacy Policy. You can unsubscribe at any time.
Discussion (0)
This website is still under development. If you encounter any issues, please contact me