################################################### # This Compose file provides the development environment for the todo app. # # Seeing the final version of the application bundles the frontend with the # backend, we are able to "simulate" that by using a proxy to route requests # to the appropriate service. All requests to /api will be routed to the # backend while all other requests will be sent to the client service. While # there is some overlap in the routing rules, the proxy determines the service # based on the most specific rule. # # To support easier debugging and troubleshooting, phpMyAdmin is also included # to provide a web interface to the MySQL database. ################################################### ################################################### # Services # # The services define the individual components of our application stack. # For each service, a separate container will be launched. ################################################### services: ################################################### # Service: proxy # # This service is a reverse proxy that will route requests to the appropriate # service. Think of it like a HTTP router or a load balancer. It simply # forwards requests and allows us to simulate the final version of the # application where the frontend and backend are bundled together. We can # also use it to route requests to phpMyAdmin, which won't be accessible at # localhost, but at db.localhost. # # The image for this service comes directly from Docker Hub and is a Docker # Official Image. Since Traefik can be configured in a variety of ways, we # configure it here to watch the Docker events for new containers and to use # their labels for configuration. That's why the Docker socket is mounted. # # We also expose port 80 to connect to the proxy from the host machine. ################################################### proxy: image: traefik:v2.11 command: --providers.docker ports: - 80:80 volumes: - /var/run/docker.sock:/var/run/docker.sock ################################################### # Service: backend # # This service is the Node.js server that provides the API for the app. # When the container starts, it will use the image that results # from building the Dockerfile, targeting the backend-dev stage. # # The Compose Watch configuration is used to automatically sync the code # from the host machine to the container. This allows the server to be # automatically reloaded when code changes are made. # # The environment variables configure the application to connect to the # database, which is also configured in this Compose file. We obviously # wouldn't hard-code these values in a production environment. But, in # dev, these values are fine. # # Finally, the labels are used to configure Traefik (the reverse proxy) with # the appropriate routing rules. In this case, all requests to localhost/api/* # will be forwarded to this service's port 3000. ################################################### backend: build: context: ./ target: backend-dev environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos develop: watch: - path: ./backend/src action: sync target: /usr/local/app/src - path: ./backend/package.json action: rebuild labels: traefik.http.routers.backend.rule: Host(`localhost`) && PathPrefix(`/api`) traefik.http.services.backend.loadbalancer.server.port: 3000 ################################################### # Service: client # # The client service is the React app that provides the frontend for the app. # When the container starts, it will use the image that results from building # the Dockerfile, targeting the dev stage. # # The Compose Watch configuration is used to automatically sync the code from # the host machine to the container. This allows the client to be automatically # reloaded when code changes are made. # # The labels are used to configure Traefik (the reverse proxy) with the # appropriate routing rules. In this case, all requests to localhost will be # forwarded to this service's port 5173. ################################################### client: build: context: ./ target: client-dev develop: watch: - path: ./client/src action: sync target: /usr/local/app/src - path: ./client/package.json action: rebuild labels: traefik.http.routers.client.rule: Host(`localhost`) traefik.http.services.client.loadbalancer.server.port: 5173 ################################################### # Service: mysql # # The MySQL service is used to provide the database for the application. # The image for this service comes directly from Docker Hub and is a Docker # Official Image. # The data is persisted in a volume named todo-mysql-data. Using a volume # allows us to take down the services without losing the data. When we start # the services again, the data will still be there (assuming we didn't delete # the volume, of course!). # # The environment variables configure the root password and the name of the # database to create. Since these are used only for local development, it's # ok to hard-code them here. ################################################### mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos ################################################### # Service: phpmyadmin # # This service provides a web interface to the MySQL database. It's useful # for debugging and troubleshooting data, schemas, and more. The image for # this service comes directly from Docker Hub and is a Docker Official Image. # # The environment variables configure the connection to the database and # provide the default credentials, letting us immediately open the interface # without needing to log in. # # The labels are used to configure Traefik (the reverse proxy) with the # routing rules. In this case, all requests to db.localhost will be forwarded # to this service's port 80. ################################################### phpmyadmin: image: phpmyadmin environment: PMA_HOST: mysql PMA_USER: root PMA_PASSWORD: secret labels: traefik.http.routers.phpmyadmin.rule: Host(`db.localhost`) traefik.http.services.phpmyadmin.loadbalancer.server.port: 80 ################################################### # Volumes # # For this application stack, we only have one volume. It's used to persist the # data for the MySQL service. We are only going to use the default values, # hence the lack of any configuration for the volume. ################################################### volumes: todo-mysql-data: