Search code examples
phpdockerorientdbdocker-composeprovisioning

Keep container alive and linked using docker-compose


I want to use docker-compose to compose together php and several databases (orientdb, neo4j, etc). Then get into the php container and use the shell to execute commands.

Individually, all of my container work swimmingly, and when I compose them together, they all run. However, I cannot for the life of me figure out how to keep the php container alive so I can get into it for testing.

For simplicity, I'll just use a single database: orient-db.

My docker-compose.yml file:

version: '2'
services:
  php:
    build: .
    links:
       - orientdb

  orientdb:
    image: orientdb:latest
    environment:
      ORIENTDB_ROOT_PASSWORD: rootpwd
    ports:
       - "2424:2424"
       - "2480:2480"

My "php" Dockerfile:

FROM php:5.6-cli
ADD . /spider
WORKDIR /spider
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
RUN composer install --prefer-source --no-interaction

RUN yes | pecl install xdebug \
    && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini

I have tried (among other things):

  • docker-compose up in one terminal and then docker attach in another
  • enabling tty and stdin_open in my compose file
  • using a /bin/bash command
  • variations of CMD exec vendor/bin/phpunit -D FOREGROUND

And some references I've tried:


Solution

  • So docker-compose is just a stand-in for the docker-engine client. It maintains feature parity with the client. For diagnosing problems like this, you should drop the use of docker-compose until you get it working with the regular ole client. Based on your comments here and on the other answer, it just sounds like you're not running a container with a daemon process in the foreground. If you want to run an interactive shell in Docker, you have to use the -it flags (-t allocates a tty and -i initiates an interactive session). If you don't run Docker with those switches, your container won't survive you starting an interactive shell, e.g. php -a.

    It helps to think of Docker as a fancy way to run a process and not a virtual machine. It's not some "environment" that exists outside of the lifetime of whatever process (and its children) you are running. Normally, PHP is invoked by some server (e.g. Apache, Nginx, etc). What you're implying here is that you need a PHP process to run "permanently" so that you can drop into the container and test some things. Except for the interactive shell, that's not going to be possible, and you need specifically to use the -it switch to keep an interactive shell process alive in your container. The real answer here is that you can't do what you're trying to do here (keep a PHP container running) without some related daemon/server process listening in the foreground. The reason for that is because that's not how PHP works. If you really want to get into a container from your PHP image, just drop into a shell on it:

    docker run -it apollo/php /bin/bash
    

    ... And you'll start a container from your PHP image, and get a shell on the container (which will die as soon as you exit the shell). But again, just reiterating from my first paragraph, docker-compose is not the way to go here.