Make sure to check out ross's approach!
Docker let's you overcome hypervisors. So let's check it out:
## docker-compose.yml
php:
image: doerty/fpm # see below
ports:
- "mysql:3306:3306"
expose:
- 9000
volumes:
- ./html:/var/www/html # The webdir containing the actual CMS
- ./fpm.conf:/root/php-fpm.conf # FPM Config because we might need to change something
- ./php.ini:/root/php.ini # PHP Config because the unchanged timezone error is annoying
command: /usr/local/sbin/php-fpm --fpm-config /root/php-fpm.conf -c /root --force-stderr
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: asdf
MYSQL_USER: asdf
MYSQL_PASSWORD: asdf
expose:
- 3306
volumes:
- ./db/:/var/lib/mysql/ # I think having this on a per-project basis is kinda neat
nginx:
image: nginx:latest
links:
- php
expose:
- 80
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html # The actual webdir, see above
- ./nginx.local:/etc/nginx/nginx.conf # The (full) nginx config
Okay so... why overwrite the default PHP/FPM Container? There are a couple'a caveats here:
## doerty/fpm/Dockerfile
FROM php:5.6-fpm
# This is the user FPM will run as. Your machine (if linux) will probably run as UID/GID 1000, and www-data had the uid of 33
# when i first booted the thing. So instead of fiddling around with guids you could just as well create a new user for FPM to
# run as. Also: Create a tmp dir for given user.
RUN groupadd -g 1000 fpm \
&& adduser --disabled-login --disabled-password --gecos "" --home /var/www/html --shell /bin/false --uid 1000 --ingroup fpm fpm \
&& mkdir /var/www/tmp && chown fpm:fpm /var/www/tmp
# Install modules. [The PHP container's manual](https://github.com/docker-library/docs/tree/master/php) teaches us how to install
# PHP modules via Dockerfile, so let's make use of that in order to get rid of mbstring / gd missing warnings. Afterwards, because
# Docker, clear the apt dir to shorten the Container size.
RUN apt-get update && apt-get install -y \
apt-utils \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng12-dev \
&& docker-php-ext-install mcrypt mbstring \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd \
&& rm -rf /var/lib/apt/lists/*
docker build doerty/fpm
, docker tag $yourtag doerty/fpm
and we're good to go.
FPM Config: change the user / group to "fpm", change the access.log to "/proc/self/fd/2" in order to make them pop up @ your STDOUT docker-compose terminal, chroot into /var/www/html/, php_admin_value[error_log] = "/proc/self/fd/2" done (optional, if you skip the php.ini).
PHP Config: set the timezone, session.save_path = "/var/www/tmp", switch from displaying the errors to logging mode.
Done. Hf.
If mysql just won't let you connect directly you can use a dirty hack: PHP's ini configuration allows you to set default DSNs for PDO to use! So share a common php.orig.ini into the php container, in which you basically say:
pdo.dsn.myboltinstall = "mysql:host=%%ENV_MYSQL_HOST%%;dbname=myboltinstall"
Then as a starting command you'll fire off a bashscript which reads the freshly created mysql-container's IP from the environment vars and replaces the ENV_MYSQL_HOST directive like:
ip=$(env | grep MYSQL_PORT_3306_TCP_ADDR | grep -oe '[^=]*$')
/bin/sed -e "s/%%ENV_MYSQL_HOST%%/$ip/g" /root/php.orig.ini > /root/php.ini
/usr/local/sbin/php-fpm --fpm-config /root/php-fpm.conf -c /root --force-stderr
Easy enough. What PHP's PDO constructor now allows you to do is:
$pdo = new PDO("myboltinstall", 'username', 'password', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
When you omit the driver, the dbname etc you can use your newly created DSN string from the PHP config. How would that look like in the app/config.yml
?
database:
dsn: 'myboltinstall'
username: 'username'
password: 'password'
Why would we do such a thing? Docker provides all the neccessary informations as environment variables. In some cases you just can't connect to MySQL using the linked port, even if you expose it. When some day I know why I'll drop a note here. In order to use environment variables inside the app/config.yml
you'd have to install a symfony plugin (iirc, correct me if I'm wrong). Notice though: this is a hack! Containercluster setups probably have problems here. Also with every IP change you'd have to re-write the php.ini. But when you use said bash script as a container start command you can simply destroy the container and re-create it. Again: THIS IS A HACK! But it'll get you working if you really need it.