Skip to content

docs(deploy): VPS hosting gotchas and workarounds #324

Description

@fpindej

Summary

Lessons learned from deploying the demo to a budget VPS. These should be documented or fixed in the production overlay.

Issues Encountered

1. pids_limit conflicts with deploy.resources.limits.pids

Newer Docker Compose rejects having both the legacy top-level pids_limit (from the x-hardened anchor) and deploy.resources.limits.pids on the same service.

Fix: Remove pids_limit from x-hardened, set pids inside each service's deploy.resources.limits instead.

2. PostgreSQL / Redis / MinIO crash with cap_drop: ALL + no-new-privileges

The x-hardened anchor drops all capabilities and sets no-new-privileges. Infrastructure services (Postgres, Redis, MinIO) need CHOWN, SETUID, SETGID, FOWNER, DAC_OVERRIDE for their entrypoint user-switching and data directory permissions.

Fix: Override security_opt and cap_add on db, redis, and storage services to add back the minimum required capabilities.

3. MinIO requires x86-64-v2 CPU instruction set

MinIO's official images (both minio/minio from Docker Hub and quay.io/minio/minio) are compiled with x86-64-v2 requirement. Budget VPS hosts with older CPUs (pre-Haswell) fail with Fatal glibc error: CPU does not support x86-64-v2.

Workaround: Use SeaweedFS (chrislusf/seaweedfs) as a drop-in S3-compatible replacement. It's a Go binary with no glibc dependency. Requires a startup config for S3 credentials:

storage:
  image: chrislusf/seaweedfs:latest
  command:
    - sh
    - -c
    - |
      printf '{"identities":[{"name":"admin","credentials":[{"accessKey":"%s","secretKey":"%s"}],"actions":["Admin","Read","Write","List","Tagging"]}]}' "$$S3_ACCESS_KEY" "$$S3_SECRET_KEY" > /tmp/s3.json
      exec weed server -s3 -s3.port=9000 -s3.config=/tmp/s3.json -dir=/data

4. Redis health check SSL mismatch

StackExchange.Redis defaults to SSL in production. The containerized Redis runs plain TCP. Without explicitly setting Caching__Redis__UseSsl=false, the API fails to connect with SslStream.AuthenticateAsClient errors.

Fix: Set Caching__Redis__UseSsl: "false" in the API's environment block.

Affected Files

  • deploy/docker-compose.production.yml
  • deploy/envs/production-example/api.env (should document UseSsl=false)
  • deploy/docker-compose.yml (base topology, storage service)

Labels

Production overlay, deployment, infrastructure

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions