phundament / app

Dockerized Yii2 web application base
http://phundament.com
Other
310 stars 129 forks source link

MongoDB integration in phundament problem #187

Closed sum1190 closed 8 years ago

sum1190 commented 8 years ago

Hi all,

I'm doing a private project with Phundament, and I need to integrate MongoDB in it. While I can succesfully use in local envroinment, the dockerized version say to me this:

PHP Fatal Error 'yii\base\ErrorException' with message 'Class 'MongoClient' not found'

In my Dockerfile I have: RUN apt-get update && apt-get install -y libxslt-dev libxslt1.1 libssl-dev php5-mongo RUN pecl install mongo && docker-php-ext-enable mongo

and if I do docker-compose up: appfpm_1 | [24-Nov-2015 08:25:09] WARNING: [pool www] child 9 said into stderr: "2015-11-24 08:25:09 [172.17.0.1][-][78f4d96c3884bf0ba9e29d664d97679e][error][yii\base\ErrorException:1] exception 'yii\base\ErrorException' with message 'Class 'MongoClient' not found' in /app/vendor/olomedia/yii2-olodoc/components/OlodocHelpers.php:15"

schmunk42 commented 8 years ago

Do you have yii2-mongodb installed in the dockerized version in composer.json and composer.lock?

You may need to build the Docker images again with make docker-build and also update your local installation (vendor is usually a host-volume in development) with make app-install.

sum1190 commented 8 years ago

I've trying what you told me, but the problem persist. I'm trying to find where the problem could be but with Docker is not easy as a local installation..

schmunk42 commented 8 years ago

Looks like MongoClient is deprecated, see http://php.net/manual/de/class.mongoclient.php

I think this one gets installed http://php.net/manual/de/set.mongodb.php

I don't know from the top of my head how to install the old client. Are you using yii2-mongodb?

sum1190 commented 8 years ago

yes I'm using yii2-mongodb.

I'm sorry to not have seen the deprecation note, but if the library is not supported anymore, why local version of my app works and not the dockerized version?

schmunk42 commented 8 years ago

Could you compare your phpinfo() dockerized vs. local outputs, especially the version of the PHP mongo-extension. I haven't used mongo lately, so I am more guessing than really knowing what's the problem.

sum1190 commented 8 years ago

It's really strange.. I'm seeing that in the dockerized version the mongo extension is not loaded but that's really strange because the installation is completed succesfully. At this point is clear that the problem is that the container can't find the extension, and to me is a big problem because I've tried to make it work :/

EDIT: yii2-mongodb uses the old version of the driver, installed with pecl install mongo

schmunk42 commented 8 years ago

How did you check?

I added your lines for testing and was able to see mongo-db, at least with php -i | grep mongo on CLI.

schmunk42 commented 8 years ago

I tried these lines in my Dockerfile:

RUN apt-get update && apt-get install -y libxslt-dev libxslt1.1 libssl-dev
RUN pecl install mongo
RUN docker-php-ext-enable mongo

Result via Yii2 debug panel:

bildschirmfoto 2015-11-24 um 20 37 03
sum1190 commented 8 years ago

I'm trying to remove the php5-mongo from apt and test again.

Yesterday I've checked with the Debug Bar inside the dockerized app.

EDIT: Debug bar say to me that mongo doesn't exist. These are the ini loaded by php: /usr/local/etc/php/conf.d/apcu.ini, /usr/local/etc/php/conf.d/app.ini, /usr/local/etc/php/conf.d/docker-php-ext-bcmath.ini, /usr/local/etc/php/conf.d/docker-php-ext-ftp.ini, /usr/local/etc/php/conf.d/docker-php-ext-gd.ini, /usr/local/etc/php/conf.d/docker-php-ext-intl.ini, /usr/local/etc/php/conf.d/docker-php-ext-mbstring.ini, /usr/local/etc/php/conf.d/docker-php-ext-mcrypt.ini, /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini, /usr/local/etc/php/conf.d/docker-php-ext-soap.ini, /usr/local/etc/php/conf.d/docker-php-ext-zip.ini, /usr/local/etc/php/conf.d/xdebug.ini

The very strange thing is that if I access in the _appcli container and launch php -i | grep mongo the output is

mongo mongo.allow_empty_keys => 0 => 0 mongo.chunk_size => 261120 => 261120 mongo.cmd => $ => $ mongo.default_host => localhost => localhost mongo.default_port => 27017 => 27017 mongo.is_master_interval => 15 => 15 mongo.long_as_object => 0 => 0 mongo.native_long => 1 => 1 mongo.ping_interval => 5 => 5

and php --ini

/usr/local/etc/php/conf.d/docker-php-ext-bcmath.ini, /usr/local/etc/php/conf.d/docker-php-ext-gd.ini, /usr/local/etc/php/conf.d/docker-php-ext-intl.ini, /usr/local/etc/php/conf.d/docker-php-ext-mbstring.ini, /usr/local/etc/php/conf.d/docker-php-ext-mcrypt.ini, /usr/local/etc/php/conf.d/docker-php-ext-mongo.ini, /usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini, /usr/local/etc/php/conf.d/docker-php-ext-soap.ini, /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini, /usr/local/etc/php/conf.d/docker-php-ext-xsl.ini, /usr/local/etc/php/conf.d/docker-php-ext-zip.ini

EDIT2: Maybe the problem is in the appfpm in my case, the container appcli has the mongo driver installed, but appfpm not..

schmunk42 commented 8 years ago

Ah! So I think it's missing in the fpm container.

We're working on a setup with a combined fpm+cli image: Here's the current version: https://hub.docker.com/r/phundament/php-one/ And this is the source: https://git.hrzg.de/phundament/docker-php-one

Could you try to depend on this image:

FROM phundament/php-one:5.6-fpm

And you need to build your CLI and FPM container then ... or use a docker-compose.yml like this*

appphp:
  # should be replaced with image, eg. <project_name>_appsrc
  build: .
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'mongo:mongo'
    - 'mariadb:DB'

appnginx:
  image: phundament/nginx-one:1.9
  links:
    - 'appphp:PHPFPM'
  # host-volume for local development
  volumes:
    - '.:/app'
  ports:
    - '80'

mongo:
  image: mongo
  restart: always

(*) untested

sum1190 commented 8 years ago

I've tested your docker-compose version and I think it's the right way to solve this problem. Now I'm pretty sure that the container is generated with the Mongo driver installed, but now I've another problem: the container doesn't communicate between each others.

appphp:
  # should be replaced with image, eg. <project_name>_appsrc
  build: .
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'mongodb:mongo'
    - 'mariadb:DB'

# The nginx server for serving static files directly
appnginx:
  image: phundament/nginx-one:1.9
  links:
    - 'appphp:PHPFPM'
  # host-volume for local development
  volumes:
    - '.:/app'
    #- 'build/nginx/run.sh:/root/run.sh'
  ports:
    - '80'
  environment:
    VIRTUAL_HOST: '~^dev\.myapp\.'

# Data Services
# -------------
mariadb:
  image: tutum/mariadb:10.1
  ports:
    - '3309:3306'
  environment:
    MARIADB_PASS: secretadmin
schmunk42 commented 8 years ago

Check /etc/hosts inside the container. Mongo should be available in the PHP by "virtual host" mongo, the alias of the link.

sum1190 commented 8 years ago

I'm trying to getting it works, now on docker-compose up docker say to me that:

appnginx_1   | 2015/11/26 08:15:01 [emerg] 7#7: host not found in upstream "phpfpm" in /etc/nginx/nginx.conf:53
appnginx_1   | nginx: [emerg] host not found in upstream "phpfpm" in /etc/nginx/nginx.conf:53
schmunk42 commented 8 years ago

Do you have a link like below in your docker-compose.yml?

 links:
    - 'appphp:PHPFPM'

Can you post your docker-compose.yml and docker version?

sum1190 commented 8 years ago
# container to run one-off commands - a dockerized shell
appphp:
  # should be replaced with image, eg. <project_name>_appsrc
  build: .
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'mongodb:MONGODB'
    - 'mariadb:DB'
  command: 'sh src/run.sh'

# The nginx server for serving static files directly
appnginx:
  image: phundament/nginx-one:1.9
  # host-volume for local development
  links:
    - 'appphp:PHPFPM'
    #- 'build/nginx/run.sh:/root/run.sh'
  ports:
    - '80'
  environment:
    VIRTUAL_HOST: '~^dev\.myapp\.'

# Data Services
# -------------
mariadb:
  image: tutum/mariadb:10.1
  ports:
    - '3309:3306'
  environment:
    MARIADB_PASS: secretadmin
#  volumes:
#    - ./environment/mariadb/data:/var/lib/mysql

mongodb:
  image: mongo:latest
  volumes:
    - '.:/app'
  ports:
    - "27017:27017"
    - "28017:28017"
  command: 'mongod --rest --httpinterface --storageEngine wiredTiger'

PS. In the old version of Phundament's docker-compose file, Cli and nginx were linked and nginx was linked with fpm. Now only with two container, if I try to link appcli (+fpm) with appnginx I get an error, something like "Circular import between.."

schmunk42 commented 8 years ago

You're missing a host-volumes for nginx:

appnginx:
  image: phundament/nginx-one:1.9
  volumes:
    - '.:/app'
sum1190 commented 8 years ago

I'm sorry I forgot to edit the post, I've added it after I've posted here. Still don't work.

Now I'm trying the Ambassador pattern to fix the "circular import" error between appphp and appnginx

schmunk42 commented 8 years ago

Which docker and docker-compose version do you use?

sum1190 commented 8 years ago

Sorry, my mind reject the first time you asked to me, here the version of docker and docker-compose:

$ docker -v
Docker version 1.9.1, build a34a1d5
$ docker-compose -v
docker-compose version: 1.5.1
sum1190 commented 8 years ago

I think that I've solved the problem right now, but not with the docker-compose.yml that you've posted here, but with the old one..

appfpm:
  image: phundament/php:5.6-fpm-4.4.1-dev
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'mariadb:DB'
    - 'mongodb'
  command: bash -c "pecl install mongo && docker-php-ext-enable mongo && /bin/bash /root/run-phundament.sh"

look at "command:" where i've inserted the command to install the mongo driver for php, than in my .env

MONGO_HOST = ${MONGODB_1_PORT_27017_TCP_ADDR}
MONGO_PORT = ${MONGODB_1_PORT_27017_TCP_PORT}

just like Phundament do for MariaDB. Do you think that it is an elegant way to solve this problem?

schmunk42 commented 8 years ago

It delayes your startup quite a bit. A better solution would be to build a custom fpm image.

That's the reason why we decided to combine cli and fpm back in the one image again (php-one).

You could still try the following (we did this with older projects), see also https://github.com/phundament/app/issues/187#issuecomment-159568668 ...

RUN pecl install mongo && docker-php-ext-enable mongo 

Could you give this a try, I am pretty sure it will work.

sum1190 commented 8 years ago
# Phundament 4 - Local Development Stack
# ======================================

# Application services
# --------------------

# container to run one-off commands - a dockerized shell
appcli:
  # should be replaced with image, eg. <project_name>_appsrc
  build: .
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'appnginx:WEB'
    - 'mariadb:DB'
    - 'mongodb'
  command: 'sh src/run.sh'

# The php-fpm server for interpreting php code
appfpm:
  build: .
  # host-volume for local development
  volumes:
    - '.:/app'
  links:
    - 'mariadb:DB'
    - 'mongodb'
  command: bash -c "pecl install mongo && docker-php-ext-enable mongo && /bin/bash /root/run-phundament.sh"

# The nginx server for serving static files directly
appnginx:
  image: schmunk42/nginx:1.9
  links:
    - 'appfpm:PHPFPM'
    - 'mariadb:DB'
    - 'mongodb'
  # host-volume for local development
  volumes:
    - '.:/app'
    #- 'build/nginx/run.sh:/root/run.sh'
  ports:
    - '80'
  environment:
    VIRTUAL_HOST: '~^dev\.myapp\.'

# Build-container with CLI and source-code
appsrc:
  build: .
  command: 'tail -f /dev/null'
  # host-volume for local development
  volumes:
    - '.:/app'
    - '/home/sum/.ssh:/root/.ssh'

# Data Services
# -------------
mariadb:
  image: tutum/mariadb:10.1
  ports:
    - '3309:3306'
  environment:
    MARIADB_PASS: secretadmin
#  volumes:
#    - ./environment/mariadb/data:/var/lib/mysql

mongodb:
  image: mongo:latest
  volumes:
    - '.:/app'
  ports:
    - "27017:27017"
    - "28017:28017"
  command: 'mongod --rest --httpinterface --storageEngine wiredTiger'

rabbit_mng:
  image: rabbitmq:management
  volumes:
   - '.:/app'
  ports:
    - "15672:15672"
    - "25672:25672"
    - "5672:5672"
    - "4369:4369"

Dockerfile

FROM phundament/php-one:5.6-fpm-4.5.3

# Clean eventually orphaned files and remove installation source
RUN rm -rf /app/src /app/web /app-src && \
    mkdir -p /root/.ssh

ADD .ssh /root/.ssh
RUN ls -la /root/.ssh

# Prepare container
# /!\ Note: Please add your own API token to config.json
# Phundament comes with a public token for your convenince which may hit the GitHub rate limit
ADD ./build/container-files/ /

# install linux package and php ext
RUN apt-get update && apt-get install -y libxslt-dev libxslt1.1 libssl-dev
RUN pecl install mongo && docker-php-ext-enable mongo && docker-php-ext-install xsl sockets && docker-php-ext-configure bcmath && docker-php-ext-install bcmath

# Install application packages, if there are changes the composer files
ADD ./composer.lock ./composer.json /app/
RUN /usr/local/bin/composer install --prefer-dist --optimize-autoloader

# Add application code
ADD version /app/version
ADD .env-dist /app/.env
ADD yii Dockerfile docker-compose.yml /app/
ADD web /app/web
ADD src /app/src

# Create folder writable by the application (non-persistent data)
RUN mkdir -p /app/web/assets /app/runtime && \
    chmod 777 /app/web/assets /app/runtime
ERROR: Cannot start container 9228d3eacc01e0531cc52ab1a338081e513dcabf5de1d63f4e7dd365e3cea458: Cannot link to a non running container: /pages_appfpm_1 AS /pages_appnginx_1/pages_appfpm_1
schmunk42 commented 8 years ago

Replace

  command: bash -c "pecl install mongo && docker-php-ext-enable mongo && /bin/bash /root/run-phundament.sh"

with UPDATED

  command: "sh /root/run.sh"

in appfpm

[edit]

There should be an error in docker-compose logs btw.

sum1190 commented 8 years ago

It works also in this way! :) Should I consider this issue closed? How can I send you a virtual coffee to thank you?

schmunk42 commented 8 years ago

You're welcome ;)