Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › DevOps

Docker Compose Examples for Self-Hosting Apps on a VPS

By Freedom251 Team · · 10 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Docker Compose can run a complete self-hosted application stack on one VPS: the application, database, reverse proxy, and supporting services are defined as reproducible containers. A production deployment differs from a development file because it must persist data, protect secrets, limit public ports, wait for healthy dependencies, terminate HTTPS, and provide a recovery path.

This guide gives you a reusable Compose foundation, a production override, and practical patterns for WordPress, Ghost, and Nextcloud. Replace the example images, paths, health probes, and environment names with the exact values required by each project’s current documentation.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What a Compose deployment on a VPS actually does

A VPS is a remote Linux server with its own CPU, memory, disk, network interface, and public IP address. Docker Engine runs containers on that server, while Compose describes how those containers connect, start, store data, and receive configuration. Docker’s production guidance notes that the easiest way to deploy an application is to run it on a single server, much like the development environment.

Compose is an orchestrator for one host, not a replacement for backups, patching, monitoring, or capacity planning. A sound design normally has an application container, a database container, and a reverse proxy. Only the proxy listens on the public web ports; the database and application communicate over private Docker networks.

#1 Best Overall
Sale
TOZO A1 Wireless Earbuds Bluetooth 5.3 Light Weight in Ear Headphones | IPX5 Waterproof,2 Mics for AI Calls,Immersive Premium Sound Bass Headset with Charging Case,32 EQ via App Black
  • [Ultra-Lightweight Ear Buds Designed for Small Ears] Each earbud weighs only 3.7g and features a compact, ergonomic in-ear design made especially for small ears. Secure, low-profile, and comfortable for workouts, all-day wear or overnight sleeping.The ultra-slim profile sits flush in your ear with no hard edges poking or rubbing, so you can even sleep on your side without discomfort.
  • [Immersive Stereo Sound with TOZO OrigX Technology] TOZO OrigX tuning delivers clear vocals, balanced mids, and natural stereo sound for music, podcasts, and videos.
  • [Long Battery Life for Daily Use] Get up to 7 hours of playtime on a single charge, with up to 32 hours total using the charging case—ideal for workdays, commuting, and extended listening sessions.
  • [Bluetooth 5.3 & Stable Connection] Bluetooth 5.3 provides fast pairing, stable wireless performance, and reduced dropouts as you move around home or office.
  • [Deep Bass with Clear Vocals] High-performance drivers produce punchy bass while keeping vocals clean and detailed for everyday listening.

Prepare the VPS before writing YAML

Install and lock down the host

  • Choose a Linux distribution and Docker Engine version supported by the applications you intend to run. Install the current Docker Compose plugin from Docker’s installation instructions.
  • Create a dedicated deployment directory owned by a non-root operational account. Keep SSH administration separate from routine Compose commands where your security policy allows.
  • Restrict SSH access, apply security updates, and configure a host firewall. For a normal web stack, allow SSH and TCP ports 80 and 443; open other ports only when an application explicitly requires them.
  • Point the application’s DNS records at the VPS, but delay public traffic until the stack passes local health and restore tests.
  • Track disk usage. Container logs, database files, uploaded media, and backups can all grow independently.

Do not promise a fixed CPU, RAM, or disk size for every app. A small brochure site and a busy file-sharing instance have very different requirements. Estimate from the application’s support matrix, database size, concurrent users, upload volume, and backup retention, then leave headroom for updates and temporary database operations.

Use a predictable project layout

my-app/
  compose.yaml
  compose.production.yaml
  .env.example
  secrets/
    db_password.txt
  backups/
  README.md

Keep the real .env file and everything under secrets/ out of version control. Give secret files restrictive permissions and ensure the deployment account, not every local user, can read them. Pin image tags after checking the target application’s compatibility matrix; silently tracking latest makes rollback and incident analysis unnecessarily difficult.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A reusable base Compose file

The following pattern separates a front network (for the proxy and web-facing services) from a back network marked internal. The application and database use named volumes so replacing a container does not erase state. The database healthcheck gives Compose a readiness signal rather than relying only on container start order.

services:
  app:
    image: example/app:1.2
    restart: unless-stopped
    networks: [front, back]
    environment:
      DATABASE_HOST: db
      DATABASE_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - app_data:/var/lib/example

  db:
    image: postgres:16
    restart: unless-stopped
    networks: [back]
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5

  proxy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    networks: [front]
    volumes:
      - caddy_data:/data
      - caddy_config:/config

volumes:
  app_data:
  db_data:
  caddy_data:
  caddy_config:

secrets:
  db_password:
    file: ./secrets/db_password.txt

networks:
  front:
  back:
    internal: true

A named volume stores data on the host outside the container lifecycle. Removing and recreating a database container therefore does not remove its database files, but deleting the volume does. Treat volume deletion as a destructive operation and require an explicit backup first.

Rank #2
Sale
Smart Watch for Men Women Compatible with iPhone Samsung Android Phone 1.69 inch Full Touch Screen IP68 Waterproof Bluetooh Fitness Tracker Heart Rate/Sleep Monitor (Black)
  • 【IP68 Waterproof Multifunctinal Smart Watch】Torjalph fitness activity tracker smart watch is IP68 waterproof technology ,you can wear it when swimming,handwashing,it's rain-proof which means that you perform multiple exercise modes outside without worrying about sweat or rain corroding your fitness smart watch,and this watch equipped with a 230 mAh large capacity battery magnetic charging ,and this sports activity tracker watch can be used 5-7 days If fully charged.
  • 【Larger 1.83'' Full Screen Watch & Multi-dial Selection】1.83 inch full HD color touch screen smart watch for men / women provides excellent 240*284 resolution image quality ,This Bluetooth smart watch offers a better touch experience and remarkable immersion and ,more than 200 watch faces for you to choose from App"Da Fit ", you can change the dial style according to your mood to wear keeping the world on your wrist
  • 【Accurate Activity Tracker Smart Watch 】sports watch activity tracker uses sweat and dust resistant breathable silicone strap, our Fitness Tracker Smart Watch for Android iOS Phones supports 12 sports modes,walking,running,bicycle,swimming,badminton,basketball,football,rope skipping. This bluetooth calls smart watch for men women is lightweight and stylish, bringing more convenient and relaxing sports experience while also providing more protection.
  • 【Your 24 Hour Personal Daily Health Monitor】Fitness watch for women men full touch screen IP67 waterproof bluetooth smartwatch for Android iOS Phones with heart rate blood pressure monitor multifunction Andriod smart watch with steps counter sleep monitor sports fitness watch, monitoring blood oxygen saturation allows you to understand your physical condition in real time to track fitness progress ,to know your health status in time.
  • 【More Functions Bluetooth Call Smart Watch】This fitness activity smart watch full screen for iPhone and Android phones includes a bunch of new features including:The bluetooth smart watch can hang up the phone, receive and display WhatsAPP /Text /Facebook /Twitter /Messenger reminder.Support sedentary reminder, alarm clock, stopwatch, timer,weather information,music control, remote camera control compatible with Android 5.0 and above or iOS 9.0 and above smartphones.

Why each section exists

  • restart: Restarts a process after a crash or host reboot; it does not replace health monitoring or fix a bad configuration.
  • networks: The proxy can reach the application on front; the application reaches the database on back. Marking back internal prevents direct external routing.
  • secrets: Compose mounts the password as a file at /run/secrets/db_password only in services that list it.
  • depends_on with health: The application waits for the database healthcheck to pass. This is readiness ordering, not a guarantee that migrations or application-level initialization have completed.
  • healthcheck: Use the database client’s real readiness command. Replace it when using a different database engine.

Add production behavior with an override file

Keep development-friendly defaults in compose.yaml and add production-only restrictions in compose.production.yaml. Review the merged result before applying it.

services:
  app:
    ports: []
    logging:
      options:
        max-size: "10m"
        max-file: "3"
  db:
    ports: []

The empty ports lists make it explicit that the application and database are not published directly. Deploy and inspect the rendered configuration with:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
docker compose -f compose.yaml -f compose.production.yaml config
docker compose -f compose.yaml -f compose.production.yaml up -d
docker compose ps
docker compose logs --tail=100 app

Check the output of config for unexpected interpolated values, host bindings, image tags, mounts, and networks. To rebuild and recreate one service without touching its dependencies, use:

docker compose build web
docker compose up --no-deps -d web

Use the complete file list consistently in automation and documentation; running a command with only the base file can accidentally publish development ports or omit production settings.

Rank #3
New Bee Guitar Cable 10ft Electric Instrument Bass AMP Cord | 6.35mm Jack, Durable Design, Stage and Home Studio Use, Low Noise Shielded Electric Cord for Bass, Keyboard, Amp, Mixer
  • [Low Noise High Fidelity] New bee guitar cord with 22AWG oxygen-free-copper center conductors provides enhanced signal transfer, the PVC insulation material and the high-density stranded copper double shield provide noise rejection for quiet operation
  • [Ideal for Choice] New bee 1/4 straight and right angle metal connectors, ensures a secure connection in any instrument, pedal, or amp jack. L shape great fro on stage guitar stands
  • [Wide Compatible] Suitable for mixer, power amplifier, microphone, effector, decoder, equalizer, electoronic organ, electric guitar, electric bass and other electronic equipments. Widely used in the installation of smart home, karaoke speaker, professional stage audio, etc
  • [Easy Disassemble] Making incidental repairs quick and easy! Very nice, flexible cable
  • [Dont Hesite to Order] 24 hours customer services and professional technology team are standing by

Terminate HTTPS at a reverse proxy

Point DNS to the VPS and let the proxy own ports 80 and 443. Persist the proxy’s certificate and configuration directories in named volumes so certificate state survives container replacement. The proxy forwards requests to the application over the private front network and should preserve the original host, scheme, and client address headers required by the application.

Never expose an application’s internal port merely because it is convenient for testing. If temporary direct access is unavoidable, bind it to 127.0.0.1, remove the mapping before public launch, and verify with docker compose config.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

WordPress with MySQL

The official WordPress/MySQL Compose sample is a useful starting point. Adapt it so MySQL is attached only to the back network, its data directory is a named volume, and WordPress is reachable from the proxy rather than from a public host port. Where the image supports *_FILE variables, provide the database password through a Compose secret file.

Production checks

  • Use a MySQL healthcheck and make WordPress depend on that health status.
  • Persist the WordPress content volume, including uploaded media and installed plugins.
  • Test media uploads, permalink rewrites, scheduled tasks (cron), and administrator login through HTTPS.
  • Back up both the database dump and the content volume. A database-only backup cannot restore uploaded files; a files-only backup cannot restore posts and settings.
  • Before upgrading, record the current image tags and take a verified backup. Roll back the image only when the database schema remains compatible with that version.

Ghost with MySQL 8

Ghost’s production requirements are specific: MySQL 8, HTTPS, and a reverse proxy that sends X-Forwarded-For, X-Forwarded-Host, and X-Forwarded-Proto: https. Set Ghost’s url configuration to the real HTTPS domain, not an internal container name or HTTP address.

Rank #4
BSIMB 15.6" Digital Family Calendar & Chore Chart, No Subscription Fees
  • Digital Family Calendar: BSIMB digital calendar wall touch screen puts an end to your chaotic life. Designed for busy families, the digital calendar keeps you organised and in step with your family. Assign different colours and tasks to each family member to make family scheduling easier and more intuitive.
  • Easy Setup and Auto-Sync: Plug in, connect to WLAN and auto-syn your electric calendar in minutes. Digital wall calendar compatible with Google calendar, iCloud calendar, Outlook calendar, Cozi calendar and Yahoo calendar. Add events directly on the device or through the ecalendar app. Electronic calendar stays current whether you're at work or traveling—no manual updates needed.
  • All-In-One Home Assistant: Smart calendar builds habits and encourage independence with personalised chores. Display daily meal plan to reduce the daily ‘What's for dinner?’ stress. To-do lists keep track of everything you want. Turning chores into valuable achievements with stars and rewards, making life easier and more enjoyable.
  • Manage Anytime Anywhere: BSIMB electronic calendar for family stay connected with the powerful ecalendar app. Access and manage your digital wall calendar anytime, anywhere with free features like stars & rewards, photo screensaver, chore charts, meals plans, to-do lists etc. Electronic planner paid features like Magic Import tailor advanced tools for users with special needs.
  • Stay in Touch with Loved Ones: Share photos or videos from your phone to electronic wall calendar with app, instantly update your life moment, and keep in touch with your family, especially those who are far away; you can also surprise your smart calendar digital wall by sending him a wish card; it's also great for keeping tech-illiterate elders in touch with the youngsters.

Compose design

  • Run Ghost and MySQL 8 on the private back network, with a persistent Ghost content volume and a persistent MySQL data volume.
  • Publish only the proxy’s 80/443 bindings. Do not map Ghost’s internal port to the VPS interface.
  • Inject the database password using a secret mechanism supported by the selected image and verify the image’s exact variable names.
  • Confirm that the proxy forwards the three required headers; incorrect scheme information commonly causes redirect loops or mixed-content behavior.

Test post creation, image upload, admin access, canonical redirects, and certificate renewal before switching DNS or declaring the deployment production-ready.

Nextcloud behind a proxy

Nextcloud’s basic container setup does not provide SSL and is intended to run behind a reverse proxy. Persist the Nextcloud data volume and database, and configure trusted proxy addresses explicitly. Trust only the proxy’s private IP address or a narrowly defined private CIDR; trusting arbitrary networks allows spoofed client information.

Operational requirements

  • Set the application’s trusted-proxy and overwrite-protocol settings according to the proxy topology so generated links use HTTPS.
  • Add Redis when the supported Nextcloud deployment requires it for locking or transactional file operations; place Redis on the private network and do not publish its port.
  • Verify WebDAV, large-file uploads, background jobs, sharing links, and forwarded-proto behavior through the public hostname.
  • Back up the database and the complete data volume, then perform a restore to a separate test project before relying on the backup.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep databases and secrets private

Public exposure should be an explicit exception. In a normal web stack, the firewall and Compose port mappings expose SSH, 80, and 443 only. Database ports, Redis, internal admin endpoints, and application listeners stay on private Docker networks. Binding a port to 0.0.0.0 publishes it on every host interface; omit the mapping entirely when the proxy is the only intended entry point.

Compose secrets are mounted files, not encrypted storage. Protect the host, restrict file permissions, avoid committing secret files, and rotate credentials when staff, machines, or repositories change. Do not bake passwords into images or place long-lived production credentials in a tracked environment file.

Backups, upgrades, and rollback

Back up what is stateful

  • Dump each database with its native tool and retain the dump outside the VPS.
  • Archive named volumes containing uploads, configuration, certificates, and application state.
  • Keep backups on separate storage from the server being backed up and document retention and encryption.
  • Perform a trial restore. A backup that has never been restored is an unverified assumption.

Update one service at a time

  1. Read the application and database release notes and confirm supported version combinations.
  2. Save a database dump, volume snapshot or archive, and the currently running image tag.
  3. Pull or build the new image, then recreate only the target service where possible.
  4. Inspect healthchecks, logs, migrations, HTTPS responses, uploads, and background jobs.
  5. Keep the previous image tag and backup until the new release has operated successfully for a defined observation period.

A rollback is not always a simple image change: a migration may make a database incompatible with the older application. Restore the database backup first when the release notes require it, then redeploy the known-good image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Compare the three common stacks

Stack Application and database Persistent data and backup Public exposure Readiness and HTTPS considerations
WordPress WordPress with MySQL; use the versions supported by the official sample and image. WordPress content volume plus MySQL data volume; back up both and a database dump. Proxy on 80/443; WordPress and MySQL private. MySQL healthcheck; test uploads, rewrites, cron, and restore.
Ghost Ghost requires MySQL 8 for production. Ghost content and MySQL data volumes; archive content and dump MySQL. Do not publish Ghost’s internal port; proxy handles 80/443. HTTPS, real domain in url, and X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto: https.
Nextcloud Nextcloud with its supported database; add Redis when required by the deployment. Nextcloud data volume plus database (and Redis configuration if persistent); test a full restore. Proxy is public; database and Redis remain private. Explicit trusted-proxy settings; verify WebDAV, large uploads, jobs, and forwarded HTTPS.

Exact CPU, RAM, disk, and traffic requirements are not universal values. Size each VPS from the selected application’s guidance and your workload, then monitor real usage before increasing limits or moving to multiple hosts.

Troubleshoot by symptom

The application starts before the database

Inspect docker compose ps and the database healthcheck logs. Confirm the probe uses the right user, database name, and client command. Keep depends_on with condition: service_healthy, but also make the application retry connections because a healthy database can become temporarily unavailable later.

HTTPS redirects loop or links use HTTP

Verify the proxy’s forwarded-host and forwarded-proto headers, the application’s canonical URL, and any trusted-proxy or overwrite-protocol setting. Test from the public hostname rather than an internal container address.

Data disappeared after a redeploy

Run docker volume ls and inspect the service’s rendered mounts with docker compose config. Confirm that the expected named volume is attached at the application’s documented data path and that nobody ran a command with volume removal.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A container repeatedly restarts

Read recent logs, check the resolved environment and secret mounts, and compare the image tag with the application’s supported database version. A restart policy can hide a persistent configuration error by repeatedly relaunching the same failing process.

Launch checklist

  1. Install supported Docker Engine and Compose versions on a patched VPS.
  2. Create a non-root project directory and protect .env and secret files.
  3. Define private back-end networks, named volumes, healthchecks, and restart policies.
  4. Expose only the reverse proxy and required public ports.
  5. Render and inspect the merged production configuration.
  6. Start the stack and review docker compose ps and service logs.
  7. Verify HTTPS, application-specific headers, uploads, jobs, and authentication.
  8. Back up volumes and databases to storage outside the VPS and test a restore.
  9. Monitor disk growth, certificate renewal, restart counts, and logs.
  10. Document image tags, rollback steps, and the person responsible for updates.

A single VPS running Compose is a practical way to self-host when you deliberately separate public traffic from private services, persist state outside containers, inject secrets safely, and rehearse recovery. The YAML is only the beginning; repeatable operations and tested backups are what make the deployment dependable.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

DevOpsDocker ComposeghostHTTPSLinuxNextcloudreverse proxyself-hostingVPSWordPress

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.