Pietro
Pietro

Reputation: 1835

Dockerized Django with webpackDevServer

I need some help with a Docker configuration to make Django work with webpack dev server in development mode. I want django docker container to get access to the webpack generated bundle.

I'm struggling to understand how containers share files with volumes in docker-compose.

Until now I only managed to have a working django dockerized app and then I run npm install && node server.js locally.

Dockerfile

# use base python image with python 2.7
FROM python:2.7
ENV PYTHONUNBUFFERED 1

# set working directory to /code/
RUN mkdir /code
WORKDIR /code

# add requirements.txt to the image
ADD requirements.txt /code/

# install python dependencies
RUN pip install -r requirements.txt

ADD . /code/

# Port to expose
EXPOSE 8000

docker-compose.yml

version: '2'
services:
  db:
    image: postgres
  redis:
    image: redis
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"  # we forward this port because it's useful for debugging
      - "15672:15672"  # here, we can access rabbitmq management plugin
  worker:
    build: .
    command: celery worker -A example -l info
    volumes:
      - .:/code
    links:
      - db
      - rabbitmq
      - redis
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
      - ./assets/bundles:/webpack (here I'm trying in some way to address webpack files to assets/bundles)
    ports:
      - "8000:8000"
    links:
      - db
      - rabbitmq
      - redis

And this is my attempt with webpack

Dockerfile.webpack

FROM node:latest

WORKDIR /webpack
COPY package.json /webpack/
COPY server.js /webpack/

RUN npm config set registry http://registry.npmjs.org/ && npm install

ADD . /webpack/

# Port to expose
EXPOSE 3000

this is the snippet added to docker-compose.yml

webpack:
    build:
      context: .
      dockerfile: Dockerfile.webpack
    command: node server.js
    volumes:
      - .:/webpack
    ports:
      - "3000:3000"

server.js

var webpack = require('webpack')
var WebpackDevServer = require('webpack-dev-server')
var config = require('./webpack.config')

new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  inline: true,
  historyApiFallback: true
}).listen(3000, '0.0.0.0', function (err, result) {
  if (err) {
    console.log(err)
  }

  console.log('Listening at 0.0.0.0:3000')
})

Upvotes: 3

Views: 2196

Answers (2)

Pietro
Pietro

Reputation: 1835

Thanks to this SO thread I found the solution.

docker-compose.yml

version: '2'
services:
  webpack:
    build:
      context: .
      dockerfile: docker/webpack
    volumes_from:
      - webapp:rw

  webapp:
    build:
      context: .
      dockerfile: docker/webapp
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"

docker/webapp

FROM python:latest
ENV PYTHONUNBUFFERED 1

# set working directory to /code/
RUN mkdir /code
WORKDIR /code

# add requirements.txt to the image
ADD ./requirements.txt /code/

# install python dependencies
RUN pip install -r requirements.txt

ADD . /code/

# Port to expose
EXPOSE 8000

docker/webpack

from node:latest

RUN npm install webpack -g

ADD docker/start-webpack.sh .
RUN chmod +x /start-webpack.sh

CMD ./start-webpack.sh

docker/start-webpack.sh

#!/usr/bin/env bash

until cd /code && npm install
do
  echo "Retrying npm install"
done

webpack --watch --watch-polling

Upvotes: 5

Filip Dupanović
Filip Dupanović

Reputation: 33650

When using the webpack-dev-server, the actual outputs go to an in-memory output filesystem, so the only way to access the bundle from Django would be to either provide clients with a URL to the public path where the bundle is returned by webpack-dev-server, or extend how the static assets are discovered and gathered to retrieve these over HTTP if only Django can access the Webpack container.

Now that that's covered, I'd recommend that you do not do it. Instead, use webpack $ARGS and webpack --watch $DEV_ARGS. This will write the outputs to the volume, which you can then share with Django.

Upvotes: 1

Related Questions