Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to develop with docker and Yii2

Docker Development Workflow

These ideas are WORK IN PROGRESS!

Summary

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

  1. start with an image and put all our initial code and dependencies in there,
  2. then develop new features
  3. and finally commit changes into a new image revision whenever we feel ready for another release.
  4. 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:

1. Initialize the project

  • Prepare our initial project files in a directory (e.g. app/)
  • Create an initial Dockerfile that also COPYs 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?)

2. Develop

  • 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.

3. Prepare a release

  • 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

Example

  • 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 replace localhost with the IP of your VM if you're on Win/OsX).

Best practices

  • 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.

Tips

  • 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
@piksar
Copy link

piksar commented Oct 29, 2015

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..

Copy link

ghost commented Nov 17, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment