Developing in a Docker Container

Introduction

In a previous article, I wrote about creating a Docker container for an existing Django project. The Dockerfile in that article copies the source code directly into the Docker image. This is good when you are ready to release the app to production but slows development because you have to rebuild the entire image whenever you change the code.

Solution

To immediately see changes to code, we can mount a volume to our container. Start with the project that we created in the previous article. You can find the source code on BitBucket. Be sure to first checkout the docker-containertag and create your own branch to work on.

Now create a new file in the root of the project named docker-compose.yml and add the following contents:

version: '3'

services:
  backend:
    build: .
    volumes:
      - .:/src/
    ports:
      - "8000:8000"

Then from the command-line run

$ docker-compose up -d

This will run all of the services listed in our docker-compose.yml file. For the backend service, we tell docker-compose to build a Docker image with the build: . directive. This looks for the Dockerfile in the current directory. We also specify the port mapping when the container runs. The important part for our purposes is volumes which mounts the current directory as /src/ inside the container.

As before, you can navigate to http://localhost:8000/rest/ to view the Django Rest Framework interface for our baseball card API.

Add a New Route to the API

Now we will add a new model and corresponding views. First, open rest/models.py and add the following model above the BaseballCard model:

class CardSet(models.Model):
    name = models.CharField(max_length=255)

Then add a field to the existing BaseballCard model:

card_set = models.ForeignKey(to=CardSet, on_delete=models.PROTECT, null=True, blank=True)

Next add a serializer for our new model in rest/serializers.py:

class CardSetSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.CardSet
        fields = '__all__'

Then add a viewset to rest/views.py:

class CardSetViewSet(viewsets.ModelViewSet):
    queryset = models.CardSet.objects.all()
    serializer_class = serializers.CardSetSerializer

And finally, register the viewset in rest/urls.py:

router.register(r'card_sets', views.CardSetViewSet)

Now open http://localhost:8000/rest/ or refresh the page in your browser. You will see the new route listed as shown in the screenshot.

Conclusion

We set up a Docker container with volumes mounted to the local file system. This allows the Docker container to automatically reflect changes to your code while you develop your project.

Facebook
Twitter
LinkedIn
Pinterest