Ben Thomson
Ben Thomson

Reputation: 1143

How to setup multiple visual studio solutions working together using docker compose (with debugging)

Lots of questions seem to have been asked about getting multiple projects inside a single solution working with docker compose but none that address multiple solutions.

To set the scene, we have multiple .NET Core APIs each as a separate VS 2019 solution. They all need to be able to use (as a minimum) the same RabbitMQ container running locally as this deals with all of the communication between the services.

I have been able to get this setup working for a single solution by:

enter image description here

Now when I launch all new RabbitMQ and MongoDB containers are created.

I then did exactly the same thing with another solution and unsurprisingly it wasn't able to start because the RabbitMQ ports were already in use (i.e. it tried to create another new RabbitMQ image).

I kind of expected this but don't know the best/right way to properly configure this and any help or advice would be greatly appreciated.

Upvotes: 3

Views: 3560

Answers (2)

Ben Thomson
Ben Thomson

Reputation: 1143

So I thought I would answer my own question as I think I eventually found a good (not perfect) solution. I did the following steps:

  1. Created a custom docker network.
  2. Created a single docker-compose.yml for my RabbitMQ, SQL Server and MongoDB containers (using my custom network).
  3. Setup docker-compose container orchestration support for each service (right click on the API project and choose add container orchestration).
  4. The above step creates the docker-compose project in the solution with docker-compose.yml and docker-compose.override.yml
  5. I then edit the docker-compose.yml so that the containers use my custom docker network and also specifically specify the port numbers (so they're consistently the same).
  6. I edited the docker-compose.override.yml environment variables so that my connection strings point to the relevant container names on my docker network (i.e. RabbitMQ, SQL Server and MongoDB) - no more need to worry about IPs and when I set the solution to startup using docker-compose project in debug mode my debug containers can access those services.
  7. Now I can close the VS solution and go to the command line and navigate to the solution folder and run 'docker-compose up' to start the container.
  8. I setup each VS solution as per steps 3-7 and can start up any/all services locally without the need to open VS anymore (provided I don't need to debug).
  9. When I need to debug/change a service I stop the specific container (i.e. 'docker container stop containerId' and then open the solution in VS and start it in debug mode/make changes etc.
  10. If I pull down changes by anyone else I re-build the relevant container on the command line by going to the solution folder and running 'docker-compose build'.
  11. As a brucey bonus I wrote PowerShell script to start all of my containers using each docker-compose file as well as one to build them all so when I turn on my laptop I simply run that and my full dev environment and 10 services are up and running.

For the most part this works great but with some caveats:

  • I use https and dev-certs and sometimes things don't play well and I have to clean the certs/re-trust them because kestrel throws errors and expects the certificate to be trusted, have a certain name and to be trusted. I'm working on improving this but you could always not use https locally in dev.
  • if you're using your own nuget server like me you'll need to a Nuget.config file and copy that as part of your docker files.

Upvotes: 2

swatsonpicken
swatsonpicken

Reputation: 883

I have been able to compose multiple services from multiple solutions by setting the value of context to the appropriate relative path. Using your docker-compose example and adding my-other-api-project you end up with something like:

services:
    my-api-project:
      <as you have it currently>

    my-other-api-project:
      image: ${DOCKER_REGISTRY-}my-other-api-project
      build:
        context: ../my-other-api-project/    <-- Or whatever the relative path is to your other project
        dockerfile: my-other-api-project/Dockerfile
      ports:
          - <your port mappings>
      depends_on:
        - some-mongo
        - some-rabbit

    some-rabbit:
      <as you have it currently>

    some-mongo:
      <as you have it currently>

Upvotes: 2

Related Questions