We're preparing to launch a house-rental application and want a production setup that is secure, affordable, scalable, and easy for a small team to maintain. The application will handle many property images, so we're also deciding how those files should be stored, processed, and delivered efficiently.
We're considering Docker, Kubernetes, Terraform, Prometheus/Grafana, and GitHub Actions. For those with startup production experience, what approach would you recommend? In particular, how would you handle image uploads and delivery without making the infrastructure unnecessarily expensive or complex? I'd appreciate recommendations for what to use now and what can reasonably wait until the application grows.
5 Answers
Separate the application deployment from image storage. Put property photos in private object storage such as S3, Google Cloud Storage, or R2, then serve them through a CDN. The browser can upload using short-lived signed URLs, while the backend restricts object names, file sizes, and content types. Validate the actual file signature too, and strip EXIF metadata because photos may contain GPS information.
A background worker can generate a few fixed image sizes instead of resizing every image during a request. A service like Cloudinary is worth considering if you need many dynamic transformations; otherwise, object storage plus a CDN is usually simpler.
For the application, use a managed container platform such as Cloud Run, ECS Fargate, or Fly, along with a managed database. Check how each platform supports background jobs before choosing. Docker provides a useful, portable deployment unit, while GitHub Actions can build and deploy immutable versioned images with straightforward rollbacks. Keep database migrations backward-compatible, since reverting an application image does not revert a migration.
Kubernetes and self-managed monitoring can wait until you have a measurable reason to operate them. Terraform is useful once manually recreating environments becomes risky. From the beginning, add tested database restores, uptime checks, error tracking, separate production secrets, billing alerts, and a documented rollback procedure.
ECS with Fargate and possibly an application load balancer would be a reasonable managed-container option. Serverless functions can also work for event-driven pieces and may be cost-effective at low usage, but consider cold starts, execution limits, and how they fit with longer-running jobs. Either way, keep the image pipeline separate from the main application and use object storage plus CDN delivery.
Start with Docker, a managed database and storage service, and automated builds and deployments. Add infrastructure-as-code and more detailed monitoring incrementally as the system becomes harder to reproduce or troubleshoot. Introduce Kubernetes only when traffic, team size, service count, or a specific operational requirement justifies its overhead. For most early-stage products, managed services provide better leverage than building a platform team before the product needs one.
Keep the initial setup deliberately boring: containerize the app, run it on a simple managed service or a small number of hosts, use GitHub Actions for deployments, and store images in object storage behind a CDN. Application servers should not be responsible for managing large media files.
Kubernetes adds ongoing operational work and usually is not worthwhile at this size unless someone on the team already has strong production experience with it. Terraform can still be valuable, but keep the configuration small and understandable enough that the team can maintain it months from now.
Managed platforms are worth considering instead of owning every part of the infrastructure. Services such as Vercel or Netlify can reduce deployment and maintenance work for suitable application components, while a specialized image service or object storage with a CDN can handle media efficiently. The right choice is not the most elaborate architecture; it is the simplest managed setup that meets current requirements and leaves a clear upgrade path as traffic and team size grow.

That makes sense. I had assumed managed platforms were mainly for small or simple applications, but I'm still learning how startups decide between managed services and operating more infrastructure themselves. For us, the main trade-offs are cost, scalability, maintenance, security, and user experience, so I'm leaning toward the simplest option that works now rather than designing for hypothetical future scale.