I've been researching a lot of practices around Docker and have come quite far. But there's one thing that keeps on puzzling me, working with data-only containers.
Here's a brief overview of my current setup:
# nginx
web:
extends:
file: _common.yml
service: web
ports:
- "80:80"
environment:
APPLICATION_ENV: prod
volumes_from:
- data
links:
- db
- redis
# php5-cli
app:
extends:
file: _common.yml
service: app
environment:
APPLICATION_ENV: prod
volumes_from:
- data
links:
- db
- redis
data:
image: <censored-url>
volumes:
- "/var/lib/mysql"
- "/app"
# percona
db:
extends:
file: _common.yml
service: db
volumes_from:
- data
# redis
redis:
extends:
file: _common.yml
service: redis
The <censored-url>
that you see is an image build with this Dockerfile:
FROM busybox
COPY . /app
Now this setup works but I just can't figure out how to handle a new release. My source is in git, when I want to deploy to production I imagine I create a new image (FROM busybox should probably be replaced with my existing image url) and pull in the new image on my production server.
But how do I get the data to update for my web container and such? I also have to make sure my persistent data (/var/lib/mysql) remains.
I hope the question is clear, I'd be happy to clarify when necessary.
Now this setup works but I just can't figure out how to handle a new release. My source is in git, when I want to deploy to production I imagine I create a new image (FROM busybox should probably be replaced with my existing image url) and pull in the new image on my production server.
Apart from the statement about busybox (which I don't follow), that seems pretty much right. Normally, you re-build the images, push to a registry, then pull from the production server. And as @Mario Marin suggests, it's worth being clever about tags, so that you can easily roll-back if needs be and you know exactly which version of your app is deployed.
But how do I get the data to update for my web container and such? I also have to make sure my persistent data (/var/lib/mysql) remains.
I assume this is referring to your data container, which you've done in a bit of an unusual way. To begin with, I would pull out the mysql directory and put it in its own data container. I would use the percona image for this so that all the permissions are set correctly. When you create the data-container, you don't leave it running, so there's no need to worry about the container getting out-of-date; it's really just a namespace for the directory.
The next step is to deal with the app directory, which I assume isn't data, but code? In this case I would include it in your web image (don't use a volume at all). In the Dockerfile I would normally do a git clone to keep the image up-to-date. During development you can mount a volume over the top of the app directory with code from the host so you can make changes instantly.
For more info on data containers, have a look at http://container42.com/2014/11/18/data-only-container-madness/