These ideas are WORK IN PROGRESS!
The core idea with this workflow is that we end up with a self contained docker image of your application. This image will not only contain our code, but also all the dependencies that are neccessary to run the code. This image can then be used for both, easy deployment in production and as basis for ongoing development.
The image is not a static, though. In fact, it will see many revisions over time - which is supported nicely through dockers inheritance approach. We basically
- start with an image and put all our initial code and dependencies in there,
- then develop new features
- and finally commit changes into a new image revision whenever we feel ready for another release.
- We finally loop back to 2.
To build both, the initial image and a new revision, we use a Dockerfile. This file basically contains a recipe for how to build your image from scratch.
Since with docker you use one container for each process we will use fig to help us manage the different containers. So you may have a web
and a db
container. fig
also helps us to map your local app code into the container, so that you can modify it on the fly during development. And fig
even builds a new image for us, whenever we want.
So let's look at the different project phases in a bit more detail:
- Prepare our initial project files in a directory (e.g.
app/
) - Create an initial Dockerfile that also
COPY
s the above directory into the image - Create a fig.yml file to describe our server setup (e.g. web, db, ...)
- Issue a
fig build web
to let docker build the initial project image
We can now distribute what we created so far:
- Commit all the above including the Dockerfile and fig.yml to your repository
- Push the docker image to a docker repository (TODO: How will this work? And how to reuse that in the fig.yml?)
- Clone your project repository
- Run
fig up
to start your environment - The local
app/
directory is shared with the running docker container, so you can now develop/modify code there. It will override whatever is stored in the docker image, so that you always can work with the latest code. - When done, you can commit and push your code as usual.
- When you're ready for a release, run
fig build web
again, to update the docker image and push that image. (TODO: How to tag that image with fig?) - Pull this latest image to production and start a container from there
- Create a new Yii2 project in an
app/
directory
composer create-project --prefer-dist --stability=dev yiisoft/yii2-app-basic basic
- Modify the configuration to use environment variables e.g. for DB host credentials
'db' => [
'dsn' => 'mysql:host='.getenv('DB_PORT_3306_TCP_ADDR').';dbname=yii',
'username' => 'app',
'password' => 'secret',
],
- Create a
Dockerfile
with a minimal PHP setup
FROM debian:wheezy
# Modify the PHP modules below to match your project requirements
RUN apt-get update && \
apt-get install -y \
php5-cli \
php5-imagick \
php5-intl \
php5-mcrypt \
php5-mysql \
php-apc && \
rm -rf /var/lib/apt/lists/*
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin && \
ln -s /usr/local/bin/composer.phar /usr/local/bin/composer
COPY app/ /app
- Create a
fig.yml
web:
build: .
command: php -S 0.0.0.0:8000 -t /app/web
ports:
- "8000:8000"
volumes:
- ./app:/app
links:
- db
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: secretroot
MYSQL_USER: app
MYSQL_PASSWORD: secret
MYSQL_DATABASE: yii
- Run
fig up
to start your setup. You should be able to access http://localhost:8000 (you may have to replacelocalhost
with the IP of your VM if you're on Win/OsX).
- Use one container per process
- Make the containers self contained! I.e. include all your app code and app dependencies (No more provisioning on deployment!)
- Build ephemeral containers! You should be able to exchange your container in production without data loss.
- Configure the containers through environment variables. Some environment variables are automatically provided by docker. You can pass more into the container through your
fig.yml
. In your PHP application you can also use phpdotenv to use a.env
file for configuration.
- To install a composer package you fire a one-off command:
fig run web composer require some/package
- To run yii migrations, open fire up the container (
fig up
) then from a second terminal window do
fig run web /app/yii migrate --interactive=0
Good idea, I just want to comment that FIG is now deprecated and replaced with Docker Compose.
I am also looking at otto ( https://ottoproject.io) to achieve this..