{
  "id": 4919422,
  "title": "From Zero to Staging: A Real-World Laravel + Node.js Docker Deployment (With Every Bug We Hit)",
  "url": "https://urgent.news/2026/09/01/from-zero-to-staging-a-real-world-laravel-node-js-docker-deployment",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-01T19:00:08.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/dineshstack/from-zero-to-staging-a-real-world-laravel-nodejs-docker-deployment-with-every-bug-we-hit-fn3"
  },
  "original_language": "en",
  "account": "From Zero to Staging: A Real-World Laravel + Node.js Docker Deployment (With Every Bug We Hit)\n\nThe Setup\nA production server (api.dineshstack.ae) hosted a Laravel 12 + Node.js microservices stack within Docker. To create a staging environment identical to production for mobile testing, the existing staging server required a complete overhaul. The server was previously used by five developers, leaving behind a mess of outdated projects, unwanted Docker volumes, and faulty nginx configurations.\n\nGoal\nThe objective was to create a clean server, one Docker network, and three domains with zero stale state.\n\nSSH Hardening\nBefore making any changes on the shared server, it's essential to survey the environment. Generating a dedicated SSH key for the server prevents password confusion. The key was added to the server and an alias was added to the ~/.ssh/config file. This way, connecting to the server became as simple as typing \"ssh dstack_staging\". The server was then secured by disabling password authentication and enabling public key authentication. Fail2ban was also installed for added security.\n\nServer Survey\nBefore eliminating any remnants of the old setup, the server was surveyed to understand what was taking up space and what was running. Disk space was analyzed, containers were listed, networks and volumes were checked. The findings included 49 GB across 8 stale project folders, three Docker Compose setups, 11 nginx site configurations, and one container holding live data that needed to be preserved. This information was critical to ensure no critical data was unintentionally removed.\n\nFull Server Reset\nThe server was then reset by stopping and removing all containers, removing stale named volumes, and deleting stale networks and project folders. The disk space went down from 70 GB used (73%) to 21 GB (22%). This amounted to a 49 GB recovery in under ten minutes.\n\nFresh Deployment\nA fresh deployment was then made by cloning the projects, configuring .env files, and starting the Docker stack in the correct order. The process involved starting infrastructure services first, followed by Laravel and Node.js services after ensuring MySQL and Kafka were healthy. A bug encountered during this process was the delay of the queue, scheduler, and Reverb containers due to their dependencies on MySQL being healthy. The bug was fixed by waiting for MySQL to show as healthy before running the Docker compose up command again.",
  "summary": "From Zero to Staging: A Real-World Laravel + Node.js Docker Deployment (With Every Bug We Hit) A step-by-step walkthrough of setting up a clean staging server from scratch — SSH hardening, Docker orchestration, Let's Encrypt SSL, database seeding, and debugging a login that refused to work for six different reasons. The Setup We had a production server ( api.dineshstack.ae ) running a Laravel 12…",
  "key_points": [
    "Dedicated SSH key and config alias for secure server access",
    "Server survey revealed 49 GB of stale data and configurations",
    "Fresh deployment restored server to 21 GB usage with correct Docker order"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}