How I Streamlined My Development Workflow with Docker Compose
This is a small, multi-service stack that I used to replace ad-hoc local processes. The stack runs a web app, a Postgres database and a reverse proxy. I wrote a single Docker Compose file to bring them up together. The aim was simple: predictable environments, faster onboarding and less time fiddling with ports, volumes and networking.
Overview of the application stack
- A web service (Node.js or similar) that serves the app.
- A Postgres service for data.
- An nginx reverse proxy for local TLS and routing.
- A named volume for Postgres data and a user-defined network so services discover each other by name.
Key components of the Docker Compose setup
- Service definitions: image, build, ports, volumes, environment.
- Networks: a single bridge network for service discovery.
- Volumes: persistent storage for databases.
- Healthchecks: quick failure detection for the web and DB services.
Expected outcomes from the workflow
- Single command bring-up and tear-down of the whole stack.
- Reproducible local environments matching CI or staging.
- Less friction when switching branches or testing features.
- Clear steps for developers and consistent service logs.
Prerequisites
Required software installations
- Docker Engine installed and working.
- Docker Compose. Modern Docker bundles Compose V2 as the docker compose command. If your setup uses docker-compose (hyphen), adapt commands.
- A text editor and basic shell access.
Necessary accounts and permissions
- A user in the docker group or root access for running Docker commands.
- No cloud accounts needed for a local dev stack.
Basic knowledge requirements
- Comfort with the shell and editing YAML.
- Basic docker concepts: images, containers, volumes, networks.
- Familiarity with building and running containers helps, but I show the commands you need.
I tested this on a Linux desktop. Any modern Linux distro, macOS or Windows WSL2 will work. Small differences exist with macOS file sharing and Windows path handling; be aware.
Use a recent Docker Engine and Docker Compose. I ran it with the Docker Desktop bundle and the docker compose command. If you have the older docker-compose binary, the YAML is largely compatible but commands differ slightly.
The stack uses a user-defined bridge network created by Compose. That gives DNS-style service names, for example the web service can reach the database at postgres:5432. If your machine blocks Docker bridge networks (corporate VPNs sometimes do), switch to host networking for testing or adjust your firewall rules.
Setting up your Docker environment
- Install Docker and ensure the daemon runs.
- Add your user to the docker group or use sudo.
- Test with docker run –rm hello-world.
Writing the Docker Compose file Create docker-compose.yml at your project root. version: '3.8' services: web: build: ./web ports: - "3000:3000" environment: - DATABASEURL=postgres://postgres:password@postgres:5432/appdb dependson: - postgres postgres: image: postgres:15 environment: - POSTGRESPASSWORD=password - POSTGRESDB=appdb volumes: - pgdata:/var/lib/postgresql/data proxy: image: nginx:stable ports: - "80:80" volumes: - ./proxy/nginx.conf:/etc/nginx/nginx.conf:ro volumes: pgdata:
I include a healthcheck in production-adjacent setups, but keep it simple for local work.
Running your Docker Compose commands
- Build and start in detached mode:
-
docker compose up --build -d
-
- Tail logs:
-
docker compose logs -f
-
- Stop and remove:
-
docker compose down --volumes
-
Managing services and containers
- Restart a single service:
-
docker compose restart web
-
- Rebuild one service:
-
docker compose build web && docker compose up -d web
-
- Enter a running container:
-
docker compose exec web /bin/sh
-
Scaling your application
Compose supports scaling for stateless services:
-
docker compose up -d --scale web=3
Use this for simple load tests or parallel workers. Stateful services like Postgres must remain single-instance unless you add clustering.
Checking service status
-
docker compose ps
shows the status and published ports.
- docker inspect
on a container gives detailed info when you need it. - docker compose logs -f web shows realtime output.
- Add –tail 100 to limit initial output.
Watch logs while you exercise the app to confirm readiness and to catch errors early.
Testing application functionality
- Curl the proxy or open the web port in your browser.
- Check database connectivity from the app container:
-
docker compose exec web sh -c \"curl -sS http://postgres:5432 || echo 'no db' \"
-
- Run healthcheck endpoints if your app exposes them.
If a service does not respond, check its logs and health status before changing config.
Troubleshooting
Common issues and their fixes
- Port already in use: change the left side of the port mapping or stop the local process.
- Permission denied on volumes: ensure Docker has permissions for the host path or use named volumes.
- Container exits immediately: inspect logs with docker compose logs and check the CMD/ENTRYPOINT.
Debugging
- Reproduce the failure with docker compose up without -d to watch start-up.
- Use docker compose exec to run commands inside the container.
- Check network connectivity between containers with ping or nc inside one container.
- Use docker system prune -f carefully to clear stale images and volumes if storage is the problem.
Resources
- The official Docker Compose documentation covers syntax and advanced features.
- Local community forums, GitHub discussions or your team’s chat are useful when you hit environment-specific issues.
I replaced a bunch of brittle local scripts with a single docker-compose.yml. That gave me predictable environments, better logs and a repeatable developer workflow. Starting the full stack now takes a single command and a couple of minutes.
Next projects
- Add a CI job that uses the same Compose file for integration tests.
- Introduce a lightweight service mesh or service discovery if you want more advanced container orchestration.
- Swap Postgres for a managed service when you move to staging.
Resources and support
Read the official Docker Compose docs and try example stacks. If you get stuck, share the minimal docker-compose.yml and container logs when asking for help. That speeds any diagnosis.
0 Comment