Docker para desarrollo Yii2 en MacOS

En el post anterior vimos cómo crear un entorno de desarrollo para Drupal8 usando Docker.

Pero, ¿y si quiero usar otro framework de PHP, por ejemplo Yii2, en mi OSX? Es muy sencillo.

Instalación del DOCKER stack (docker4php)

docker4php miguelm$ cd Sites/testyii2
docker4php miguelm$ git clone https://github.com/wodby/docker4php
docker4php miguelm$ cd docker4php

Editar .env y dejarlo como sigue:

### Documentation available at https://docs.wodby.com/stacks/php/local
### Changelog can be found at https://github.com/wodby/docker4php/releases
### Images tags format explained at https://github.com/wodby/docker4php#images-tags

### PROJECT SETTINGS

PROJECT_NAME=unizaryii
PROJECT_BASE_URL=unizaryii.docker.localhost

DB_NAME=php
DB_USER=php
DB_PASSWORD=php
DB_ROOT_PASSWORD=password
DB_HOST=mariadb
DB_DRIVER=mysql

### --- PHP ----

#PHP_TAG=7.2-dev-4.8.2
#PHP_TAG=7.1-dev-4.8.2
#PHP_TAG=5.6-dev-4.8.2
PHP_TAG=7.2-dev-macos-4.8.2
#PHP_TAG=7.1-dev-macos-4.8.2
#PHP_TAG=5.6-dev-macos-4.8.2

### --- NGINX ----

NGINX_TAG=1.15-5.0.17
#NGINX_TAG=1.14-5.0.17

### --- NODE ---

NODE_TAG=10-0.9.0
#NODE_TAG=8-0.9.0
#NODE_TAG=6-0.9.0

### --- MARIADB ----

MARIADB_TAG=10.1-3.3.11
#MARIADB_TAG=10.2-3.3.11
#MARIADB_TAG=10.3-3.3.11

### --- POSTGRESQL ----

POSTGRES_TAG=11-1.5.0
#POSTGRES_TAG=10-1.5.0
#POSTGRES_TAG=9.6-1.5.0
#POSTGRES_TAG=9.5-1.5.0
#POSTGRES_TAG=9.4-1.5.0
#POSTGRES_TAG=9.3-1.5.0

### --- REDIS ---

REDIS_TAG=4-3.0.2
#REDIS_TAG=5-3.0.2

### --- ELASTICSEARCH ---

ELASTICSEARCH_TAG=6.3-3.0.2
#ELASTICSEARCH_TAG=6.2-3.0.2
#ELASTICSEARCH_TAG=6.1-3.0.2
#ELASTICSEARCH_TAG=6.0-3.0.2
#ELASTICSEARCH_TAG=5.6-3.0.2
#ELASTICSEARCH_TAG=5.5-3.0.2
#ELASTICSEARCH_TAG=5.4-3.0.2

### --- KIBANA ---

KIBANA_TAG=6.3-3.0.2
#KIBANA_TAG=6.2-3.0.2
#KIBANA_TAG=6.1-3.0.2
#KIBANA_TAG=6.0-3.0.2
#KIBANA_TAG=5.6-3.0.2
#KIBANA_TAG=5.5-3.0.2
#KIBANA_TAG=5.4-3.0.2

### --- SOLR ---

SOLR_TAG=7.4-3.0.6
#SOLR_TAG=7.3-3.0.6
#SOLR_TAG=7.2-3.0.6
#SOLR_TAG=7.1-3.0.6
#SOLR_TAG=6.6-3.0.6
#SOLR_TAG=5.5-3.0.6

### OTHERS

ADMINER_TAG=4.6-3.2.0
APACHE_TAG=2.4-4.0.2
ATHENAPDF_TAG=2.10.0
MEMCACHED_TAG=1-2.2.1
RSYSLOG_TAG=latest
VARNISH_TAG=4.1-3.0.10
WEBGRIND_TAG=1.5-1.6.2
OPENSMTPD_TAG=6.0-1.4.0
XHPROF_TAG=1.0.2

Compilamos y levantamos…

docker4php miguelm$ docker-compose up -d

En el fichero docker-compose.yml la variable NGINX_SERVER_ROOT tiene el valor /var/www/html/public
Así que creamos el directorio public y un fichero index.php para probar si todo ha ido bien…

docker4php miguelm$ mkdir public
docker4php miguelm$ echo "" > public/index.php

Lo siguiente será editar (como root) el fichero /etc/hosts de la máquina anfitrión y añadir algunas entradas que nos serán útiles:

127.0.0.1 unizaryii.docker.localhost
127.0.0.1 pma.unizaryii.docker.localhost

Y ya podemos ir a nuestro navegador en la máquina anfitrión: http://unizaryii.docker.localhost:8000/ y comprobar que todo funciona.

Instalación de Yii2 y creación de proyecto

Ahora que ya hemos comprobado que el setup funciona, vamos a instalar Yii2.

docker4php miguelm$ git clone https://github.com/yiisoft/yii2 _host-volumes/yii2
docker4php miguelm$ mv _host-volumes/yii2 .
docker4php miguelm$ rm -Rf _host-volumes

Y vamos a crear nuestro primer proyecto Yii2:

# eliminamos el directorio "public" completo
docker4php miguelm$ rm -Rf public
# creamos un nuevo proyecto en la carpeta "demo" 
docker4php miguelm$ composer create-project yiisoft/yii2-app-basic demo

Lo siguiente será editar el fichero docker-compose.yml para indicar el nuevo valor de NGINX_SERVER_ROOT, que deberá ser:

NGINX_SERVER_ROOT: /var/www/html/demo/web

Paramos y arrancamos los dockers con la nueva configuración:

docker4php miguelm$ docker-compose stop
docker4php miguelm$ docker-compose up -d

Ya tenemos nuestro proyecto Yii2 listo…

¿Y si en lugar de NGINX quiero utilizar Apache como servidor web?

Muy sencillo. Editamos el archivo docker-compose.yml y comentamos la sección de NGINX y descomentamos la sección de Apache. El fichero docker-compose.yml quedaría así:

version: "3"

services:
  mariadb:
    image: wodby/mariadb:$MARIADB_TAG
    container_name: "${PROJECT_NAME}_mariadb"
    stop_grace_period: 30s
    environment:
      MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
      MYSQL_DATABASE: $DB_NAME
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD
#    volumes:
#      - ./mariadb-init:/docker-entrypoint-initdb.d # Place init .sql file(s) here.
#      - /path/to/mariadb/data/on/host:/var/lib/mysql # I want to manage volumes manually.

#  postgres:
#    image: wodby/postgres:$POSTGRES_TAG
#    container_name: "${PROJECT_NAME}_postgres"
#    stop_grace_period: 30s
#    environment:
#      POSTGRES_PASSWORD: $DB_PASSWORD
#      POSTGRES_DB: $DB_NAME
#      POSTGRES_USER: $DB_USER
#    volumes:
#      - ./postgres-init:/docker-entrypoint-initdb.d # Place init file(s) here.
#      - /path/to/postgres/data/on/host:/var/lib/postgresql/data # I want to manage volumes manually.

  php:
    image: wodby/php:$PHP_TAG
    container_name: "${PROJECT_NAME}_php"
    environment:
      PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025
      DB_HOST: $DB_HOST
      DB_USER: $DB_USER
      DB_PASSWORD: $DB_PASSWORD
      DB_NAME: $DB_NAME
## Read instructions at https://wodby.com/stacks/php/docs/local/xdebug/
#      PHP_XDEBUG: 1
#      PHP_XDEBUG_DEFAULT_ENABLE: 1
#      PHP_XDEBUG_REMOTE_CONNECT_BACK: 0
#      PHP_IDE_CONFIG: serverName=my-ide
#      PHP_XDEBUG_REMOTE_HOST: 172.17.0.1 # Linux
#      PHP_XDEBUG_REMOTE_HOST: 10.254.254.254 # macOS
#      PHP_XDEBUG_REMOTE_HOST: 10.0.75.1 # Windows
    volumes:
      - ./:/var/www/html
## For macOS users (https://wodby.com/stacks/php/docs/local/docker-for-mac/)
#      - ./:/var/www/html:cached # User-guided caching
#      - docker-sync:/var/www/html # Docker-sync
## For XHProf and Xdebug profiler traces
#      - files:/mnt/files

#  nginx:
#    image: wodby/nginx:$NGINX_TAG
#    container_name: "${PROJECT_NAME}_nginx"
#    depends_on:
#      - php
#    environment:
#      NGINX_STATIC_OPEN_FILE_CACHE: "off"
#      NGINX_ERROR_LOG_LEVEL: debug
#      NGINX_BACKEND_HOST: php
#      NGINX_VHOST_PRESET: php
#      NGINX_SERVER_ROOT: /var/www/html/demo/web
#    volumes:
#      - ./:/var/www/html
# Options for macOS users (https://wodby.com/stacks/php/docs/local/docker-for-mac/)
#      - ./:/var/www/html:cached # User-guided caching
#      - docker-sync:/var/www/html # Docker-sync
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_nginx'
#      - 'traefik.port=80'
#      - 'traefik.frontend.rule=Host:${PROJECT_BASE_URL}'

  apache:
    image: wodby/apache:$APACHE_TAG
    container_name: "${PROJECT_NAME}_apache"
    depends_on:
      - php
    environment:
      APACHE_LOG_LEVEL: debug
      APACHE_BACKEND_HOST: php
      APACHE_VHOST_PRESET: php
      APACHE_DOCUMENT_ROOT: /var/www/html/demo/web
    volumes:
      - ./:/var/www/html
## For macOS users (https://wodby.com/stacks/php/docs/local/docker-for-mac/)
##      - ./:/var/www/html:cached # User-guided caching
##      - docker-sync:/var/www/html # Docker-sync
    labels:
      - 'traefik.backend=${PROJECT_NAME}_apache'
      - 'traefik.port=80'
      - 'traefik.frontend.rule=Host:${PROJECT_BASE_URL}'

  mailhog:
    image: mailhog/mailhog
    container_name: "${PROJECT_NAME}_mailhog"
    labels:
      - 'traefik.backend=${PROJECT_NAME}_mailhog'
      - 'traefik.port=8025'
      - 'traefik.frontend.rule=Host:mailhog.${PROJECT_BASE_URL}'

#  varnish:
#    image: wodby/varnish:$VARNISH_TAG
#    container_name: "${PROJECT_NAME}_varnish"
#    depends_on:
#      - nginx
#    environment:
#      VARNISH_SECRET: secret
#      VARNISH_BACKEND_HOST: nginx
#      VARNISH_BACKEND_PORT: 80
#      VARNISH_PURGE_EXTERNAL_REQUEST_HEADER: X-Real-IP
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_varnish'
#      - 'traefik.port=6081'
#      - 'traefik.frontend.rule=Host:varnish.${PROJECT_BASE_URL}'

#  redis:
#    container_name: "${PROJECT_NAME}_redis"
#    image: wodby/redis:$REDIS_TAG

#  adminer:
#    container_name: "${PROJECT_NAME}_adminer"
#    image: wodby/adminer:$ADMINER_TAG
#    environment:
## For PostgreSQL:
##      ADMINER_DEFAULT_DB_DRIVER: pgsql
#      ADMINER_DEFAULT_DB_HOST: $DB_HOST
#      ADMINER_DEFAULT_DB_NAME: $DB_NAME
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_adminer'
#      - 'traefik.port=9000'
#      - 'traefik.frontend.rule=Host:adminer.${PROJECT_BASE_URL}'

#  pma:
#    image: phpmyadmin/phpmyadmin
#    container_name: "${PROJECT_NAME}_pma"
#    environment:
#      PMA_HOST: $DB_HOST
#      PMA_USER: $DB_USER
#      PMA_PASSWORD: $DB_PASSWORD
#      PHP_UPLOAD_MAX_FILESIZE: 1G
#      PHP_MAX_INPUT_VARS: 1G
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_pma'
#      - 'traefik.port=80'
#      - 'traefik.frontend.rule=Host:pma.${PROJECT_BASE_URL}'

#  solr:
#    image: wodby/solr:$SOLR_TAG
#    container_name: "${PROJECT_NAME}_solr"
#    environment:
#      SOLR_HEAP: 1024m
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_solr'
#      - 'traefik.port=8983'
#      - 'traefik.frontend.rule=Host:solr.${PROJECT_BASE_URL}'

#  elasticsearch:
#    image: wodby/elasticsearch:$ELASTICSEARCH_TAG
#    environment:
#      ES_JAVA_OPTS: "-Xms500m -Xmx500m"
#    ulimits:
#      memlock:
#        soft: -1
#        hard: -1

#  kibana:
#    image: wodby/kibana:$KIBANA_TAG
#    depends_on:
#      - elasticsearch
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_kibana'
#      - 'traefik.port=5601'
#      - 'traefik.frontend.rule=Host:kibana.php.docker.localhost'

#  memcached:
#    container_name: "${PROJECT_NAME}_memcached"
#    image: wodby/memcached:$MEMCACHED_TAG

#  rsyslog:
#    container_name: "${PROJECT_NAME}_rsyslog"
#    image: wodby/rsyslog:$RSYSLOG_TAG

#  athenapdf:
#    image: arachnysdocker/athenapdf-service:$ATHENAPDF_TAG
#    container_name: "${PROJECT_NAME}_athenapdf"
#    environment:
#      WEAVER_AUTH_KEY: weaver-auth-key
#      WEAVER_ATHENA_CMD: "athenapdf -S"
#      WEAVER_MAX_WORKERS: 10
#      WEAVER_MAX_CONVERSION_QUEUE: 50
#      WEAVER_WORKER_TIMEOUT: 90
#      WEAVER_CONVERSION_FALLBACK: "false"

#  node:
#    image: wodby/node:$NODE_TAG
#    container_name: "${PROJECT_NAME}_node"
#    working_dir: /app
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_node'
#      - 'traefik.port=3000'
#      - 'traefik.frontend.rule=Host:front.${PROJECT_BASE_URL}'
#    expose:
#      - "3000"
#    volumes:
#      - ./path/to/your/single-page-app:/app
#    command: sh -c 'npm install && npm run start'

#  blackfire:
#    image: blackfire/blackfire
#    environment:
#      BLACKFIRE_SERVER_ID: XXXXX
#      BLACKFIRE_SERVER_TOKEN: YYYYY

#  webgrind:
#    image: wodby/webgrind:$WEBGRIND_TAG
#    environment:
#      WEBGRIND_PROFILER_DIR: /mnt/files/xdebug/profiler
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_webgrind'
#      - 'traefik.port=8080'
#      - 'traefik.frontend.rule=Host:webgrind.php.docker.localhost'
#    volumes:
#      - files:/mnt/files

#  opensmtpd:
#    container_name: "${PROJECT_NAME}_opensmtpd"
#    image: wodby/opensmtpd:$OPENSMTPD_TAG

#  xhprof:
#    image: wodby/xhprof:$XHPROF_TAG
#    restart: always
#    volumes:
#      - files:/mnt/files
#    labels:
#      - 'traefik.backend=${PROJECT_NAME}_xhprof'
#      - 'traefik.port=8080'
#      - 'traefik.frontend.rule=Host:xhprof.${PROJECT_BASE_URL}'

  portainer:
    image: portainer/portainer
    container_name: "${PROJECT_NAME}_portainer"
    command: --no-auth -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - 'traefik.backend=${PROJECT_NAME}_portainer'
      - 'traefik.port=9000'
      - 'traefik.frontend.rule=Host:portainer.${PROJECT_BASE_URL}'

  traefik:
    image: traefik
    container_name: "${PROJECT_NAME}_traefik"
    command: -c /dev/null --web --docker --logLevel=INFO
    ports:
      - '8000:80'
#      - '8080:8080' # Dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

#volumes:
## Docker-sync for macOS users
#  docker-sync:
#    external: true
## For Xdebug profiler
#  files:

Después simplemente:

docker4php miguelm$ docker-compose up -d --remove-orphans

Entorno para desarrollo Drupal 8 en Mac: Docker con Apache + MariaDB + PHP + …

Vamos a ver cómo crear un entorno de desarrollo para Drupal 8 en OSX utilizando docker-compose. Con unos sencillos pasos conseguiremos tener montado de forma muy rápida un entorno completo que cuente con todo lo necesario para empezar a desarrollar en Drupal 8. Lo que vamos a tener será:
– MariaDB
– PHP-FPM
– Apache
– PhpMyAdmin
– Traefik
– Portainer

INSTALACIÓN DE DOCKER.

La instalación es muy sencilla. En linux ya viene preinstalado. En Mac se instala de forma muy simple, basta con seguir las instrucciones de la documentación oficial: https://docs.docker.com/docker-for-mac/install/#install-and-run-docker-for-mac

INSTALACIÓN DE dockerfordrupal

Lo primero será crear una cuenta en Docker Hub (repositorio de imgs Docker). Después abrimos Terminal y nos loggeamos:

docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: AQUITULOGIN
Password: AQUITUPASSWORD
Login Succeeded

Vamos a aprovechar el trabajo realiazdo por Wodby y clonamos su repo dockerfordrupal.

Para ello:

git clone https://github.com/wodby/docker4drupal
cd dockerfordrupal

En el directorio veremos varios archivos:

docker-compose.override.yml  docker.mk        LICENSE.md  README.md  traefik.yml
docker-compose.yml           docker-sync.yml  Makefile    tests

Vamos a modificar el fichero .env para darle nombre a nuestro proyecto (en mi caso unizar) e indicarle la base url. Para eso editaremos estas líneas.

PROJECT_NAME=unizar
PROJECT_BASE_URL=unizar.docker.localhost

El archivo docker-compose.override.yml de momento no vamos a usarlo. Es útil cuando se tienen varios entornos (desarrollo/producción) con distintos settings. En este caso lo vamos a renombrar porque editaremos directamente docker-compose.yml:

mv docker-compose.override.yml docker-compose.override.yml.back

Lo siguiente será eliminar todo el contenido de docker-compose.yml y reemplazarlo por el siguiente:

version: "3"
  
services:
  mariadb:
    image: wodby/mariadb:$MARIADB_TAG
    container_name: "${PROJECT_NAME}_mariadb"
    stop_grace_period: 30s
    environment:
      MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD
      MYSQL_DATABASE: $DB_NAME
      MYSQL_USER: $DB_USER
      MYSQL_PASSWORD: $DB_PASSWORD

  php:
    image: wodby/drupal:$DRUPAL_TAG
    container_name: "${PROJECT_NAME}_php"
    environment:
      PHP_SENDMAIL_PATH: /usr/sbin/sendmail -t -i -S mailhog:1025
      DB_HOST: $DB_HOST
      DB_USER: $DB_USER
      DB_PASSWORD: $DB_PASSWORD
      DB_NAME: $DB_NAME
      DB_DRIVER: $DB_DRIVER
      COLUMNS: 80 # Set 80 columns for docker exec -it.
## Read instructions at https://wodby.com/stacks/drupal/docs/local/xdebug/
      PHP_XDEBUG: 1
      PHP_XDEBUG_DEFAULT_ENABLE: 1
      PHP_XDEBUG_REMOTE_CONNECT_BACK: 1
      PHP_FPM_CLEAR_ENV: "no"
      #PHP_IDE_CONFIG: serverName=my-ide
      #PHP_XDEBUG_REMOTE_HOST: host.docker.internal # Docker 18.03+ & Linux/Mac/Win
      PHP_XDEBUG_REMOTE_HOST: 172.17.0.1 # Linux, Docker < 18.03
    volumes:
      - ./code:/var/www/html


  apache:
    image: wodby/apache:$APACHE_TAG
    container_name: "${PROJECT_NAME}_apache"
    depends_on:
      - php
    environment:
      APACHE_LOG_LEVEL: debug
      APACHE_BACKEND_HOST: php
      APACHE_VHOST_PRESET: php
      APACHE_DOCUMENT_ROOT: /var/www/html/web
    volumes:
      - ./code/:/var/www/html
# For macOS users (https://wodby.com/stacks/drupal/docs/local/docker-for-mac/)
#      - ./:/var/www/html:cached # User-guided caching
#      - docker-sync:/var/www/html # Docker-sync
    labels:
      - 'traefik.backend=${PROJECT_NAME}_apache'
      - 'traefik.port=80'
      - 'traefik.frontend.rule=Host:${PROJECT_BASE_URL}'


  pma:
    image: phpmyadmin/phpmyadmin
    container_name: "${PROJECT_NAME}_pma"
    environment:
      PMA_HOST: $DB_HOST
      PMA_USER: $DB_USER
      PMA_PASSWORD: $DB_PASSWORD
      PHP_UPLOAD_MAX_FILESIZE: 1G
      PHP_MAX_INPUT_VARS: 1G
    labels:
      - 'traefik.backend=${PROJECT_NAME}_pma'
      - 'traefik.port=80'
      - 'traefik.frontend.rule=Host:pma.${PROJECT_BASE_URL}'

  portainer:
    image: portainer/portainer
    container_name: "${PROJECT_NAME}_portainer"
    command: --no-auth -H unix:///var/run/docker.sock
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - 'traefik.backend=${PROJECT_NAME}_portainer'
      - 'traefik.port=9000'
      - 'traefik.frontend.rule=Host:portainer.${PROJECT_BASE_URL}'

  traefik:
    image: traefik
    container_name: "${PROJECT_NAME}_traefik"
    command: -c /dev/null --web --docker --logLevel=INFO
    ports:
      - '8000:80'
      - '8080:8080' # Dashboard
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Compilamos y construimos:

docker-compose up -d

En este momento ya podemos ver los contenedores, para ello empleamos el comando "docker-compose ps"

docker-compose ps
      Name                    Command               State                      Ports
--------------------------------------------------------------------------------------------------------
unizar_apache      /docker-entrypoint.sh sudo ...   Up      80/tcp
unizar_mariadb     /docker-entrypoint.sh mysqld     Up      3306/tcp
unizar_php         /docker-entrypoint.sh sudo ...   Up      9000/tcp
unizar_pma         /run.sh supervisord -n           Up      80/tcp, 9000/tcp
unizar_portainer   /portainer --no-auth -H un ...   Up      9000/tcp
unizar_traefik     /traefik -c /dev/null --we ...   Up      0.0.0.0:8000->80/tcp, 0.0.0.0:8080->8080/tcp

Si queremos pararlos:

docker-compose stop

Y para arrancarlos:

docker-compose start

Para ver logs:

docker-compose logs

Lo siguiente será editar (como root) el fichero /etc/hosts para indicarle algunos nombres que nos irán bien. Para ello debemos tener presente lo que escribimos anteriormente en el fichero .env. En mi caso sería así:

# /etc/hosts
127.0.0.1    unizar.docker.localhost
127.0.0.1    pma.unizar.docker.localhost
127.0.0.1    portainer.unizar.docker.localhost 

Llegados a este punto ya podremos abrir un navegador y acceder a varias direcciones:
http://unizar.docker.localhost:8000 -> para comenzar la instalación de Drupal, una vez traido el source
http://pma.unizar.docker.localhost:8000 -> para acceder a PhpMyAdmin
http://portainer.unizar.docker.localhost:8000 -> para tener una visión web de los contenedores Dockers.

Si lo que queremos es ENTRAR a la máquina host, podemos hacerlo asi:

docker-compose ps # nos da la lista de dockers que están corriendo

docker exec -it unizar_php bash # ejecutar "bash" dentro del docker llamado "unizar_php" # así mantiene la máquina "viva"

RESUELTO – Conectar a VMware VCenter desde OSX (Mac)

¿Cuál es la forma más sencilla de conectarte a VCenter desde tu Mac? Sigue los pasos del post para instalar VirtualBox y una máquina virtual Windows, después inicia la máquina virtual recién instalada, abre un navegador web, conéctate a tu VCenter y descarga e instala el cliente VMware.

Conectar a Vcenter en Mac (OSX)

Una vez lo hayas hecho, toma un snapshot (instantánea) de tu máquina en VirtualBox. Asi siempre tendrás una instantánea con el cliente vmware instalado, lista para funcionar.

Fácil y ¡gratis!

RESUELTO – Internet Explorer (IE7, IE8, IE9, IE10, IE11) en MAC (OS X)

Muchas veces nos vemos en la obligación de probar cómo se ve una web en Internet Explorer. Inexplicablemente, todavía hay muchos usuarios que emplean Internet Explorer en sus versiones más antiguas (IE6, IE7, IE8, IE9), pese a las obvias desventajas de elegir este navegador.

Internet Explorer en MAC OSX

Desde Windows resulta más sencillo. Pero, ¿cómo ejecutar Internet Explorer desde tu OS X (Mac)?

La solución es sencilla:

1. Instala VirtualBox (descargar el instalador de VirtualBox para OSX)

2. Decide qué versiones de IE quieres instalar, abre Terminal y escribe el comando adecuado en función a la versión que desees *
— Todas las versiones de IE (crearás tantas máquinas virtuales como versiones de IE se instalen)

curl -s https://raw.githubusercontent.com/xdissent/ievms/master/ievms.sh | bash

— Internet Explorer 7 (IE7):

curl -s https://raw.github.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS="7" bash

— Internet Explorer (IE8):

curl -s https://raw.github.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS="8" bash

— Internet Explorer (IE9):

curl -s https://raw.githubusercontent.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS="9" bash

— Internet Explorer (IE10):

curl -s https://raw.githubusercontent.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS="10" bash

— Internet Explorer (IE11):

curl -s https://raw.githubusercontent.com/xdissent/ievms/master/ievms.sh | IEVMS_VERSIONS="11" bash

3. Abre VirtualBox (lo tendrás instalado en “Aplicaciones” > “Virtual Box”) e inicia la máquina virtual adecuada. Se iniciará Windows y tendrás la versión de Internet Explorer que elegiste disponible. Recuerda que la contraseña por defecto de Windows es “Password1”.
Además, puedes realizar un snapshot de las máquinas para “solventar” el problema de la licencia de evaluación de 30 días que Microsoft aplica a su SO. Crea un snapshot nada más instalar las máquinas virtuales y arráncalo. Asi siempre tendrás tus 30 días de evaluación restantes.

Internet Explorer en Mac (resuelto)

* Los comandos del paso 2 son parte del ievsms script de xdissent y se encargan del proceso completo de descarga, conversión e instalación. Más fácil no puede ser 🙂

Nota: Si las URL’s de arriba no funcionan correctamente, puede ser que github haya cambiado la estructura de URL’s de raw.github.com a raw.githubusercontent.com. Corrige las URL’s superiores según este patrón.

Z39.50 command line client: YAZ CLIENT

YAZ-CLIENT is a useful command line Z39.50 client. You can install it with apt-get in your Debian box.

Connecting to Z39.50 server

You can connect to your server prividing IP Address/Port Number/Database name.
For instance I am going to connect to host=roble.unizar.es, port=210, database name=INNOPAC:

root@invenio1:~# yaz-client 
Z> open tcp:roble.unizar.es:210/INNOPAC
Connecting...OK.
Sent initrequest.
Connection accepted by v2 target.
ID     : Z39.50-III
Name   : z39-innopac
Version: 1
UserInformationfield:
{
    OCTETSTRING(len=52) Innovative Interfaces Inc. Z39.50 SERVER version 1.1
}
Guessing visiblestring:
'Innovative Interfaces Inc. Z39.50 SERVER version 1.1'
Options: search present scan namedResultSets
Elapsed: 0.178681

Getting server information

Z> list_all
Connected to         : tcp:roble.unizar.es:210/INNOPAC
auto_reconnect       : off
auto_wait            : on
Authentication       : none
Bases                : INNOPAC 
CCL file             : default.bib
CQL file             : /usr/local/share/yaz/etc/pqf.properties
Query type           : prefix (RPN sent to server)
Named Result Sets    : on
ssub/lslb/mspn       : 0/1/0
Format               : usmarc
Schema               : not set
Elements             : 
APDU log             : off
Record log           : off
Other Info:

Making a query

I am going to search records with title='”Aiche Journal” (more details on how to search by typing: man yaz-client)

Z> f @attr 1=4 "Aiche journal"
Sent searchRequest.
Received SearchResponse.
Search was a success.
Number of hits: 3, setno 1
records returned: 0
Elapsed: 0.056104

And listing results:

 

Z> show 1
Sent presentRequest (1+1).
Records: 1
[INNOPAC]Record type: USmarc
00976nas 2200253 i 4500
001 ocm00000001-1541
008 750720c19559999us mr p i 0 a0eng d
022 $a 0001-1541
022 $a 1547-5905 $b (Online)
040 $a UZ.PPE
080 $a (051)66
210 1 $a AICHE J.
222 0 $a AICHE journal $b (Print)
222 0 $a AICHE journal $b (Online)
245 00 $a AICHE journal : $b American Institute of Chemical Engineers journal / $c American Institute of Chemical Engineers.
246 13 $a American Institute of Chemical Engineers journal.
260 $a New York : $b American Institute of Chemical Engineers, $c 1955-
300 $a v. : $b il. ; $c 29 cm.
310 $a Mensual.
321 $a Trimestral $b (Mar. 1955-June 1957)
321 $a Bimestral $b (Jan. 1975-1995)
500 $a Indices de autor, t?itulo y materias de cada volumen en el ?ultimo n?umero del volumen.
650 04 $a Ingenier?ia qu?imica $v Publicaciones peri?odicas.
710 2 $a American Institute of Chemical Engineers.

nextResultSetPosition = 2
Elapsed: 0.201121

Next result…

Z> show 2
Sent presentRequest (2+1).
Records: 1
[INNOPAC]Record type: USmarc
00976nas  2200253 i 4500
001 ocm00000001-1541
008 750720c19559999us mr p  i    0   a0eng d
022    $a 0001-1541
022    $a 1547-5905 $b (Online)  
040    $a UZ.PPE
080    $a (051)66
210 1  $a AICHE J.
222  0 $a AICHE journal $b (Print)
222  0 $a AICHE journal $b (Online)
245 00 $a AICHE journal : $b American Institute of Chemical Engineers journal  / $c American Institute of Chemical Engineers.
246 13 $a American Institute of Chemical Engineers journal.
260    $a New York : $b American Institute of Chemical Engineers, $c 1955-
300    $a v. : $b il. ; $c 29 cm.
310    $a Mensual.
321    $a Trimestral $b (Mar. 1955-June 1957)
321    $a Bimestral $b (Jan. 1975-1995)
500    $a Indices de autor, t?itulo y materias de cada volumen en el ?ultimo n?umero del volumen.
650 04 $a Ingenier?ia qu?imica $v Publicaciones peri?odicas.
710 2  $a American Institute of Chemical Engineers.
 
nextResultSetPosition = 3
Elapsed: 0.013234

Using your III WebOPAC to show holding information

This will be useful if you have Innovative Millenium WebPAC.
You can show record’s holding data using b number.

For instance for record with .b1000203
HOLDINGS (english): http://roble.unizar.es/search?/.b1000203/.b1000203/1%2C1%2C1%2CB/holdings~b1000203
HOLDINGS (español): http://roble.unizar.es/search*spi?/.b1000203/.b1000203/1%2C1%2C1%2CB/holdings~b1000203
LOANS: AVAILABILTY INFORMATION: http://roble.unizar.es/search?/.b1000203/.b1000203/1%2C1%2C1%2CB/request~b1000203

Duplicate VIEWS in MySQL [SOLVED]

MySQL views are stored in information_schema.views table. You can list your views:

mysql> USE information_schema;
mysql> DESCRIBE views;
+-----------------+--------------+------+-----+---------+-------+
| FIELD           | TYPE         | NULL | KEY | DEFAULT | Extra |
+-----------------+--------------+------+-----+---------+-------+
| TABLE_CATALOG   | VARCHAR(512) | YES  |     | NULL    |       | 
| TABLE_SCHEMA    | VARCHAR(64)  | NO   |     |         |       | 
| TABLE_NAME      | VARCHAR(64)  | NO   |     |         |       | 
| VIEW_DEFINITION | longtext     | NO   |     | NULL    |       | 
| CHECK_OPTION    | VARCHAR(8)   | NO   |     |         |       | 
| IS_UPDATABLE    | VARCHAR(3)   | NO   |     |         |       | 
| DEFINER         | VARCHAR(77)  | NO   |     |         |       | 
| SECURITY_TYPE   | VARCHAR(7)   | NO   |     |         |       | 
+-----------------+--------------+------+-----+---------+-------+
8 ROWS IN SET (0.00 sec)
 
mysql> SELECT TABLE_NAME FROM views;
+---------------------------+
| TABLE_NAME                |
+---------------------------+
| uz_DOWNLOADS_TESIS        | 
| uz_DOWNLOADS_TESIS_TITLES | 
| uz_REGISTROS_BORRADOS     | 
+---------------------------+
3 ROWS IN SET, 5 warnings (0.11 sec)

You can also view who defined each view (DEFINER):

mysql> SELECT TABLE_NAME, definer FROM views;
+---------------------------+--------------------+
| TABLE_NAME                | definer            |
+---------------------------+--------------------+
| uz_DOWNLOADS_TESIS        | root@155.210.85.31 | 
| uz_DOWNLOADS_TESIS_TITLES | root@155.210.85.31 | 
| uz_REGISTROS_BORRADOS     | root@155.210.85.31 | 
+---------------------------+--------------------+
3 ROWS IN SET, 5 warnings (0.11 sec)

And you can also get the query for a view:

mysql> SELECT TABLE_NAME, view_definition FROM views;
| uz_DOWNLOADS_TESIS        | /* ALGORITHM=UNDEFINED */ (SELECT `cdsinvenio`.`rnkDOWNLOADS`.`id_bibrec` AS `id_bibrec`,`cdsinvenio`.`rnkDOWNLOADS`.`download_time` AS `download_time`,`cdsinvenio`.`rnkDOWNLOADS`.`client_host` AS `client_host`,`cdsinvenio`.`rnkDOWNLOADS`.`id_user` AS `id_user`,`cdsinvenio`.`rnkDOWNLOADS`.`id_bibdoc` AS `id_bibdoc`,`cdsinvenio`.`rnkDOWNLOADS`.`file_version` AS `file_version`,`cdsinvenio`.`rnkDOWNLOADS`.`file_format` AS `file_format`,COUNT(`cdsinvenio`.`rnkDOWNLOADS`.`id_bibrec`) AS `total` FROM `cdsinvenio`.`rnkDOWNLOADS` WHERE (`cdsinvenio`.`rnkDOWNLOADS`.`id_bibrec` IN (SELECT DISTINCT `cdsinvenio`.`bibrec_bib98x`.`id_bibrec` AS `id_bibrec` FROM `cdsinvenio`.`bibrec_bib98x` WHERE (`cdsinvenio`.`bibrec_bib98x`.`id_bibxxx` = 7)) AND (NOT(`cdsinvenio`.`rnkDOWNLOADS`.`id_bibrec` IN (SELECT DISTINCT `cdsinvenio`.`bibrec_bib98x`.`id_bibrec` AS `id_bibrec` FROM `cdsinvenio`.`bibrec_bib98x` WHERE (`cdsinvenio`.`bibrec_bib98x`.`id_bibxxx` = 3))))) GROUP BY `cdsinvenio`.`rnkDOWNLOADS`.`id_bibrec`) | 
| uz_DOWNLOADS_TESIS_TITLES | /* ALGORITHM=UNDEFINED */ (SELECT `cdsinvenio`.`bibrec_bib24x`.`id_bibrec` AS `id_bibrec`,`cdsinvenio`.`bib24x`.`value` AS `value`,`uz_DOWNLOADS_TESIS`.`total` AS `total` FROM `cdsinvenio`.`bib24x` JOIN `cdsinvenio`.`bibrec_bib24x` JOIN `cdsinvenio`.`uz_DOWNLOADS_TESIS` WHERE ((`cdsinvenio`.`bib24x`.`id` = `cdsinvenio`.`bibrec_bib24x`.`id_bibxxx`) AND (`cdsinvenio`.`bibrec_bib24x`.`id_bibrec` = `uz_DOWNLOADS_TESIS`.`id_bibrec`) AND (`cdsinvenio`.`bib24x`.`tag` = _utf8'24500a')) ORDER BY `cdsinvenio`.`bibrec_bib24x`.`id_bibrec`)
| uz_REGISTROS_BORRADOS     | /* ALGORITHM=UNDEFINED */ (SELECT DISTINCT `cdsinvenio`.`bibrec_bib98x`.`id_bibrec` AS `id_bibrec` FROM `cdsinvenio`.`bibrec_bib98x` WHERE (`cdsinvenio`.`bibrec_bib98x`.`id_bibxxx` = 3))

Knowing the query you can re-create the view with another name in another database. Original datbase was cdsinvenio, cloned database is invenio2014

mysql> USE invenio2014;
mysql> CREATE VIEW UZ_DESCARGAS_TESIS AS (SELECT `invenio2014`.`rnkDOWNLOADS`.`id_bibrec` AS `id_bibrec`,`invenio2014`.`rnkDOWNLOADS`.`download_time` AS `download_time`,`invenio2014`.`rnkDOWNLOADS`.`client_host` AS `client_host`,`invenio2014`.`rnkDOWNLOADS`.`id_user` AS `id_user`,`invenio2014`.`rnkDOWNLOADS`.`id_bibdoc` AS `id_bibdoc`,`invenio2014`.`rnkDOWNLOADS`.`file_version` AS `file_version`,`invenio2014`.`rnkDOWNLOADS`.`file_format` AS `file_format`,COUNT(`invenio2014`.`rnkDOWNLOADS`.`id_bibrec`) AS `total` FROM `invenio2014`.`rnkDOWNLOADS` WHERE (`invenio2014`.`rnkDOWNLOADS`.`id_bibrec` IN (SELECT DISTINCT `invenio2014`.`bibrec_bib98x`.`id_bibrec` AS `id_bibrec` FROM `invenio2014`.`bibrec_bib98x` WHERE (`invenio2014`.`bibrec_bib98x`.`id_bibxxx` = 7)) AND (NOT(`invenio2014`.`rnkDOWNLOADS`.`id_bibrec` IN (SELECT DISTINCT `invenio2014`.`bibrec_bib98x`.`id_bibrec` AS `id_bibrec` FROM `invenio2014`.`bibrec_bib98x` WHERE (`invenio2014`.`bibrec_bib98x`.`id_bibxxx` = 3))))) GROUP BY `invenio2014`.`rnkDOWNLOADS`.`id_bibrec`)

And to delete a view, you can do it like:

mysql> DROP VIEW uz_DOWNLOADS_TESIS;
Query OK, 0 ROWS affected (0.05 sec)

Install DISTCACHE on RHEL6 [SOLVED]

Installing distcache on RHEL6 can be tricky. Let’s see how to do it…

cd /home/miguelm/invenio113/prerequisites/distcache
wget http://sourceforge.net/projects/distcache/files/latest/download?source=files
tar -xzvf distcache-1.5.1.tar.gz
cd distcache-1.5.1

If you try to compile as is, you will get errors:

proto_fd.c: In function 'addr_parse':
proto_fd.c:177: error: 'LONG_MIN' undeclared (first use in this function)
proto_fd.c:177: error: (Each undeclared identifier is reported only once
proto_fd.c:177: error: for each function it appears in.)
proto_fd.c:177: error: 'LONG_MAX' undeclared (first use in this function)

To get rid of them, you just have to include in distcache-1.5.1/libnal/proto_fd.c as in:

#define SYS_GENERATING_LIB
 
#include <libsys/pre.h>
#include <libnal/nal.h>
#include "nal_internal.h" 
#include "ctrl_fd.h" 
#include <libsys/post.h>
#include <limits.h>
 
/**************************/
/* predeclare our vtables */
/**************************/
...

Now you can compile with no errors…

./configure --prefix=/usr
make
make install

Rename multiple files using sequence number in OSX from command line [SOLVED]

With this command you will rename all the jpg files in the current directory to PREFIX_0000.jpg to PREFIX_9999.jpg

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv %s PREFIX_%04d.jpg\n", $0, a++ }' \
| bash

If you just need two numbers (PREFIX_00.jpg to PREFIX_99.jpg) you can do it by:

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv %s PREFIX_%02d.jpg\n", $0, a++ }' \
| bash

CentOS Python crash after update: Urandom [SOLVED]

We updated our CentOS machines and when we restarted our Apache servers, and tried to access the sites, a “500 Internal Server Error” was being shown.

We noticed some ugly shit in Apache error.log:

ImportError: cannot import name urandom
[Tue Nov 27 11:45:17 2012] [error] make_obcallback: Python path being used "['/usr/lib64/python2.4/site-packages/setuptools-0.6c5-py2.4.egg', '/usr/lib64/python2.4/site-packages/rdflib-2.4.0-py2.4-linux-x86_64.egg', '/usr/lib64/python2.4/site-packages/cx_Oracle-5.0-py2.4-linux-x86_64.egg', '/usr/lib64/python2.4/site-packages/MySQL_python-1.2.2-py2.4-linux-x86_64.egg', '/usr/lib/python2.4/site-packages/pylint-0.18.1-py2.4.egg', '/usr/lib/python2.4/site-packages/logilab_astng-0.19.1-py2.4.egg', '/usr/lib/python2.4/site-packages/logilab_common-0.44.0-py2.4.egg', '/usr/lib/python2.4/site-packages/pysnmp_apps-0.2.9a-py2.4.egg', '/usr/lib/python2.4/site-packages/pysnmp-4.1.13a-py2.4.egg', '/usr/lib/python2.4/site-packages/pyasn1-0.0.11a-py2.4.egg', '/usr/lib64/python24.zip', '/usr/lib64/python2.4', '/usr/lib64/python2.4/plat-linux2', '/usr/lib64/python2.4/lib-tk', '/usr/lib64/python2.4/lib-dynload', '/usr/lib64/python2.4/site-packages', '/usr/lib64/python2.4/site-packages/Numeric', '/usr/lib64/python2.4/site-packages/gtk-2.0', '/usr/lib/python2.4/site-packages']".
[Tue Nov 27 11:45:17 2012] [error] get_interpreter: no interpreter callback found.

To fix this, you must check the following:

[root@aneto ~]# rpm -q mod_python
mod_python-3.2.8-3.1
[root@aneto ~]# rpm -q httpd
httpd-2.2.3-65.el5_8.3
[root@aneto ~]# rpm -q python
python-2.4.3-46.el5_8.2

If the output is like the one above, then run:

[root@aneto ~]# yum downgrade python python-libs

And then restart Apache. Issues should be now fixed.