v0.4.0 VM instances, a container image, a GitHub Action and testcontainers

Your own AWS,
on your own machine.

HomeCloud speaks the AWS APIs. Point Terraform, the AWS CLI or boto3 at it, and Lambda, RDS and EC2 come up as real containers and VMs on your own hardware. One binary, about 30 services, open source.

curl -fsSL https://homecloud.pages.dev/scripts/install.sh | sh

Then run homecloud serve and open 127.0.0.1:8080. Needs Docker Engine, Docker Desktop or OrbStack.

The HomeCloud console home page: a grid of services (EC2, Lambda, S3, RDS, DynamoDB, SQS, SNS, EventBridge, ECS and more) with counts of running resources in each.
~/shop — zsh
$ eval "$(homecloud aws-env)"
$ terraform apply -auto-approve
aws_s3_bucket.assets: Creation complete
aws_db_instance.orders: Creation complete
aws_lambda_function.api: Creation complete
Apply complete! Resources: 3 added.
$ docker ps --format '{{.Image}}' | head -3
postgres:17-alpine
public.ecr.aws/lambda/python:3.12
cgr.dev/chainguard/minio:latest

Tested with the tools you already use

  • AWS CLI
  • boto3
  • Terraform
  • OpenTofu
  • GitHub Actions
  • Docker
  • Testcontainers
17/17
terraform-aws-modules scenarios apply, re-plan clean and destroy, nightly
~30
AWS services behind one endpoint, with IAM enforced on every call
1 binary
API, console and CLI. Docker runs everything else
AGPL-3.0
Every feature is in the open code. There is no paid tier

How it works

Your AWS code, unchanged.

HomeCloud speaks the AWS wire protocols (SigV4, awsJson, awsQuery, REST), so the tools you already use only need a different endpoint. homecloud aws-env prints it, with the access keys it created on first start.

shellAWS CLI
# AWS_ENDPOINT_URL, keys and region
eval "$(homecloud aws-env)"

aws sts get-caller-identity
aws s3 mb s3://demo
echo hi | aws s3 cp - s3://demo/hello.txt
aws sqs create-queue --queue-name jobs
main.tfTerraform / OpenTofu
provider "aws" {
  region            = "us-east-1"
  # buckets by path, not by host name
  s3_use_path_style = true
}

resource "aws_sqs_queue" "jobs" {
  name = "jobs"
}
# the provider reads AWS_ENDPOINT_URL too
How a request flows: your tools send AWS API calls to HomeCloud on port 8080, which checks the signature and IAM policy, records the call, and runs the work as containers and VMs on Docker.

Your tools

  • aws CLI
  • boto3
  • Terraform
  • OpenTofu
  • CloudFormation

HomeCloud :8080

  1. SigV4 signature checked
  2. IAM policy evaluated
  3. CloudTrail records the call

Docker on your host

  • LambdaAWS runtime images
  • RDSPostgreSQL, MySQL
  • S3MinIO
  • EC2containers, QEMU VMs
  • ELBnginx
  • Route 53CoreDNS
Client compatibility
ClientStatusNotes
AWS CLI v2TestedThe compatibility suite drives the real aws CLI in CI.
boto3TestedIn CI, including Cognito SRP sign-in through pycognito.
Terraform, OpenTofuTestedThe stock hashicorp/aws provider, plus the nightly modules suite.
CloudFormationTestedStacks, change sets, updates with rollback, the boto3 waiters.
AWS CDKPartlySynthesized templates deploy through change sets; cdk deploy end to end is not verified yet.
Other SDKs, PulumiExpectedSame protocols and SigV4, but not covered by tests. Reports welcome.

What runs

Real infrastructure behind every API.

Each service is something real underneath, so an integration test hits the same kind of thing production does. All of it is managed through the AWS CLI, SDKs and Terraform, and shows up in the console.

Compute

Instances you can shell into.

EC2 instances are containers. Two images, Ubuntu 24.04 and Debian 12, boot real VMs under QEMU, with KVM when the host has it. EBS, AMIs, Auto Scaling, ECS (Fargate) and ECR too.

EC2 instances list with names, instance IDs, running or stopped state, instance types, images and private IPs.

Databases

The real engines.

RDSPostgreSQL · MySQL · MariaDB
ElastiCacheRedis · Valkey · Memcached
DynamoDBGSIs, transactions, PartiQL, TTL, streams
aws rds create-db-instance \
  --engine postgres --engine-version 17 \
  --db-instance-identifier orders ...
# runs postgres:17-alpine on your VPC network

Serverless

AWS's own Lambda runtimes.

aws lambda invoke \
  --function-name api:live \
  out.json
{ "StatusCode": 200,
  "ExecutedVersion": "3" }

Versions, aliases, layers, function URLs, SQS and stream triggers. API Gateway HTTP APIs and Step Functions.

Networking

What answers the call.

  • Security groupsiptables
  • ELB v2nginx
  • Route 53CoreDNS
  • ACMprivate CA
  • VPCDocker networks

Identity & security

One policy evaluator for all of it.

{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Condition": { "StringEquals":
    { "aws:PrincipalTag/team": "web" } }
}

Conditions, roles, permissions boundaries and iam:PassRole. STS, Cognito, KMS, Secrets Manager, SSM Parameter Store.

Storage

S3 on MinIO.

  • Versioning and lifecycle rules
  • Presigned URLs
  • Bucket policies
  • EFS as Docker volumes

Messaging

Fan out like production.

Standard and FIFO queues with DLQs, filter policies, EventBridge rules and Scheduler.

Observability

Metrics and logs for every resource.

CloudWatch alarms, Logs Insights, and CloudTrail: a record of every API call.

CloudWatch metrics graphs and alarms.

Infrastructure as code

CloudFormation, with rollback.

Change sets, and updates that roll back on failure. No nested stacks or custom resources yet.

17/17terraform-aws-modules scenarios pass: apply, a real check, a clean re-plan and destroy.

Limits, up front

What it is not.

  • One Docker host, one region (us-east-1), one account
  • Network ACLs and NAT gateways are recorded, not enforced
  • Not every operation of every service: check the compatibility reference
Every service, and what does the work
AreaServicesWhat does the work
ComputeEC2, EBS, AMIs, Auto Scaling, ECS (Fargate), ECRInstances are containers you can shell into. Two images, Ubuntu 24.04 and Debian 12, boot real VMs under QEMU, with KVM when the host has it.
StorageS3, EFSMinIO, with versioning, lifecycle, presigned URLs and bucket policies. EFS is Docker volumes.
DatabasesRDS, ElastiCache, DynamoDBReal PostgreSQL, MySQL and MariaDB; Redis, Valkey and Memcached. DynamoDB with GSIs, transactions, PartiQL, TTL and streams.
ServerlessLambda, API Gateway (HTTP APIs), Step FunctionsAWS's own Lambda runtime images. Versions, aliases, layers, function URLs, SQS and stream triggers.
MessagingSQS, SNS, EventBridge, SchedulerStandard and FIFO queues with DLQs; SNS to SQS, Lambda and HTTP with filter policies.
NetworkingVPC, security groups, ELB v2, Route 53, ACMSecurity groups are iptables rules. Load balancers are nginx, DNS is CoreDNS, certificates come from a private CA.
Identity & securityIAM, STS, Cognito, KMS, Secrets Manager, SSM Parameter StoreOne policy evaluator for every service, with conditions, roles, permissions boundaries and iam:PassRole.
ObservabilityCloudWatch, CloudWatch Logs, CloudTrailMetrics and logs for every resource, alarms, Logs Insights, and a record of every API call.
Infrastructure as codeCloudFormationChange sets and updates with rollback. No nested stacks or custom resources yet.

Tests & CI

A drop-in AWS for integration tests.

No cloud credentials in CI, no bill, nothing left behind. HomeCloud's own end-to-end job runs on a stock GitHub Actions runner.

.github/workflows/test.yml
steps:
  - uses: actions/checkout@v4
  - uses: solinode/homecloud/integrations/github-action@main
    with:
      services-wait: s3    # wait for MinIO too
  - run: |
      aws s3 mb s3://artifacts
      pytest               # boto3 reads AWS_ENDPOINT_URL

Downloads a checksum-verified release, starts the server, and exports the endpoint and credentials. A post step prints the server log and removes every container it started.

Testing and CI guide Terraform modules results

Console

A console in the box.

The web console is built into the binary and works offline. It is modeled on AWS's, so the layout will feel familiar. These are from the demo, which runs in your browser with sample data. Nothing to install.

Honest comparison

When to use something else.

HomeCloud is one of several ways to run AWS without AWS, and it is not always the right one.

The full comparison

HomeCloud
You want AWS APIs with real compute behind them, a console and IAM enforced, on your own machine or server, for free.
LocalStack
You need much wider service coverage (Kinesis, EKS, Athena, REST API Gateway…), several regions or accounts, or a lighter container for CI. Pro covers most of those.
moto
You want fast, in-process mocks for Python unit tests that reset between tests.
MinIO + k3s
You only need S3-compatible storage, plus Kubernetes for compute.
OpenStack
You need a multi-node private cloud with real VMs, and have people to run it.
AWS itself
You need exactly AWS's behavior. For final integration and staging tests, nothing replaces it.

Self-hosting

Built to be left running.

For a team, a classroom or a homelab, not only for a test run.

linux · macos · windows

One binary, one host

A Go binary for amd64 and arm64. Every service it offers runs as a container on the same Docker Engine.

homecloud service install

On a VPS or home server

2 vCPUs and 4 GB to try it; 4+ vCPUs and 8–16 GB to be comfortable. Sets up systemd or launchd.

127.0.0.1 → LAN, Tailscale

Reach it from elsewhere

It binds to 127.0.0.1 by default. Bind it to a LAN or Tailscale address, with built-in TLS or behind a reverse proxy.

homecloud backup

Backups

Archives the state and every HomeCloud volume: databases, S3 objects, images, EBS volumes. restore works on the same or a new server.

homecloud upgrade

Upgrades

Checks the release's SHA-256 before replacing the binary; data migrates on the next start. homecloud doctor checks the host.

/var/run/docker.sock

Security

It needs the Docker socket, which is root on the host, so HomeCloud admins are host admins. Audits are published.

Install on a server: Docker, TLS, firewall, DNS, backups and upgrades

Open source, all of it.

Licensed under the GNU AGPL-3.0. If you run a modified HomeCloud as a service for others, share your changes. It is a young project, first released in September 2026: expect rough edges and please report them. A missing AWS operation is best reported as a compatibility gap.

Supported by