Many projects require the execution of various tool commands during deployment, such as compressing static files with gulp
/grunt
, and compiling with compass
.
These tools may encounter some difficulties during Docker deployment because usually, a single image only contains one service.
Some people use integrated images, and others choose to apt-get update && apt-get install
the relevant environments, but this requires writing complex Dockerfiles, significantly prolongs the build time, and bloats the single image, which is not very Docker-like.
We can simplify this process using the volumes_from
parameter of docker-compose
:
volumes_from
Mount all of the volumes from another service or container, optionally specifying read-only access(ro) or read-write(rw).
Environment
Our sample environment looks something like this:
python
(main project)node
(npm
,bower
,grunt
)ruby
(compass
)
Compiling Files
Structure
├── Dockerfile
├── DockerfileNode
├── DockerfileRuby
├── requirements.txt
├── bower.json
├── package.json
├── config.rb
├── static
│ ├── src
│ ├── dist
│ ├── ...
├── app
│ ├── ...
Dockerfile (python)
Normal python compilation, without adding node and ruby environments
FROM python
ADD . code/
RUN pip install -r requirements.txt
# Expose port 4000 to other containers
EXPOSE 4000
CMD gunicorn --chdir /code -w 4 -b 0.0.0.0:4000 apps:app
Dockerfile (node)
FROM node
ADD . /code
WORKDIR /code
RUN npm install -g bower grunt-cli
RUN bower install --allow-root
RUN npm install
# Expose /code directory to other containers, this command must be added for using volumes_from
VOLUME /code
CMD grunt
Here we use the node image to install node-related environments, and mark the code directory as a volume
Dockerfile (ruby)
FROM ruby
ADD ./config.rb /config.rb
RUN gem install compass
CMD compass compile
Here we use the ruby image to install compass environment
docker-compose.yml
app:
build: .
node:
build: .
dockerfile: ./DockerfileNode
compass:
build: .
dockerfile: ./DockerfileRuby
# Mount the code directory from the node container, for compilation
volumes_from:
- node
nginx:
image: nginx
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
links:
- app
ports:
- 80:80
# The app(python) container no longer mounts the static files, the static files directory is directly mounted to nginx to serve
volumes_from:
- node
This compose defines 4 services:
app
- Main service
node
- Contains
bower_components
- Contains
node_modules
- Performs
grunt
compilation at runtime, after which the container automatically stops - The
/code
directory inside the container is exposed for other containers to mount
- Contains
ruby
- Contains the
compass
tool - Mounts the
/code
directory from thenode
container, performs relevant compilations at runtime
- Contains the
nginx
- Mounts the
/code
directory from thenode
container, which has been compiled bygrunt
andcompass
, and is served directly by nginx
- Mounts the
This is roughly the process. Here, the compilation command is written as CMD in the Dockerfile
, so it can be executed during container runtime. This is necessary for the compass
image, but for the node image, it can also be written as RUN in the Dockerfile
, depending on specific needs.