Search code examples
pythondockergithubarchitecturemicroservices

Is it the "Right Way" to separate Docker related files and Python related files in different git repositories?


I'm building an app with a friend, and I'm writing all the Back end code.

I started building the API, as well as setting up docker-compose, both in one Git repository. The /app directory which contains app.py, as well as my docker-compose.yml, and Dockerfile-flask, and Dockerfile-nginx all live in the same directory currently. My friend saw my code, and is telling me that all of the Docker related files should be pulled into its own Git Repo, and should just reference the Business logic repos when running the microservice.

Is this correct? And if so, could someone point me in the direction of how to implement this pattern?


Solution

  • I've seen this pattern with higher-level deployment tools (Kubernetes deployment YAML files, Helm charts, multi-service Docker Compose YAML files) but it doesn't quite make sense for a Dockerfile.

    Within the context of a single service, I'd put the Dockerfile, a local docker-compose.yml that starts that service itself, and other similar artifacts in the root directory of the service repository; or else in a subdirectory; but not in a different repository. For things that span services putting them in a different repository can make sense.

    For the Dockerfile itself, the problem is that the COPY command can't reference any files outside of the "context" directory that's passed to the docker build command, and the docker build -f option requires the Dockerfile to be there too. If the Dockerfile is in the root directory of the service then this is straightforward; if it's somewhere else then you have an awkward setup where you have to upload everything you have checked out as the docker build context directory.

    git clone ... build-scripts
    git clone ... myapp
    # This uploads everything you have checked out as the context
    docker build -f build-scripts/myapp/Dockerfile -t myapp:latest .
    

    Keeping the Dockerfile in the service repository also helps continuous-integration tools. If your CI system rebuilds things on every commit, and the Dockerfile is in the repository itself, then you can always have an up-to-date image. If the build scripts are somewhere else then you have the risk of unnecessarily rebuilding everything if any image's setup changes.

    If you need to deploy multiple services together, then it may make sense to keep these in some separate repository.

    # What directory should this `docker-compose.yml` file go in?
    version: '3'
    services:
      service-a:
        image: me/service-a:latest
      service-b:
        image: me/service-b:latest
        environment:
          - SERVICE_A_URL=http://service-a
        ports:
          - '8000:8000'
    

    Kubernetes YAML files can be a little bit of an exception to this. There tend to be several of them together (a Deployment, a Service, setup for a database dependency, ...) and they're somewhat specialized; they also depend on the image name as a reference but not the application source code themselves. I've seen a setup where Kubernetes YAML files or Helm charts are in their own repository. I've also seen setups where each repository has its own Kubernetes files. It mostly depends on whether the service authors are responsible for maintaining them, or whether you have a dedicated team that manages everything Kubernetes-related (the "source layout reflects your organizational structure" model).