Лень — двигатель прогресса или мой вариант создания окружения для веб-разработки на основе VirtualBox



Всем веб-разработчикам так или иначе нужен какой-то сервер для разработки своих веб-приложений. Кто-то использует «Денвер», кто-то OpenServer, более продвинутые берут виртуальный сервер (VPS), а еще более продвинутые используют Vagrant, а кто-то просто ленивый. Под катом я расскажу, как разворачиваю веб-приложение для разработки с помощью VirtualBox, баша и кой-каких костылей. Для тех, кто ленив и не хочет смотреть под кат: описан один баш-сценарий, который монтирует расшареные папки в гостевую ОС и полу-демон, который запускает первый сценарий после запуска перед остановкой системы и реализует интерфейс демона.

В качестве гостевой операционной системы был выбран дистрибутив линукса CentOS 6.5, в качестве веб-сервера — Apache 2.2.15.

Сразу оговорюсь: описание установки и настройки LAMP-сервера описывать не буду ибо манов в интернетах полно.

Самый первый вариант скрипта выглядел примерно так:

#!/bin/sh
mount -t vboxsf $1 $2


Постепенно он разросся в следующий скрипт:
Скрипт первый - рабочая лошадка - /root/scripts/vbox-sf.sh
#!/bin/sh

# Author:	Dmitry Vapelnik
# Email:	dvapelnik@gmail.com

# Местонахождение лог-файла
logfile='/var/log/vbox-sf.log'
# Место, куда мы будем маунтить папки
mountPrefix='/var/www/html/';
# Хостнейм-суффикс
hn='.'`hostname`
# Ищем все папки, которые были подмаунчены VirtualBox
sharedFolders=`df | egrep "\/media\/sf_\$2[^ ]*" -o | sed -e 's/\/media\/sf_//'`
#================ LOG ==========================================================#
function log {
    echo [`date +"%F %T"`] $1 $2 >> $logfile
}
#================ MOUNTING =====================================================#
function mountFn {
    echo "Mounting....";
    for f in $sharedFolders; do
	mountPath=$mountPrefix$f$hn
	if cat /proc/mounts | grep vbox | grep $mountPath &> /dev/null; then
	    echo Already mounted. Continue..;
	else
	    rm -rf $mountPath 2> /dev/null;
	    mkdir -p $mountPath;
	    chown apache:apache $mountPath;
	    if mount -t vboxsf $f $mountPath -o umask=0022,uid=apache,gid=apache; then
		echo Mounted $f
		log mounted $mountPath
		# Папки для сохранения результирующих файлов профилиования и 
		# трейсов для XDebug
		mkdir -p /var/www/html/$f$hn/xd_profile_$f$hn
		mkdir -p /var/www/html/$f$hn/xd_trace_$f$hn
		if [ -f $mountPath'/httpd.conf' ]; then
		    # Формирование конфига httpd из заранее подготовленного шаблона
		    cat $mountPath'/httpd.conf' | sed -e "s/<%domain%>/$f$hn/g" > /etc/httpd/conf/sf/$f$hn.conf
		    if [ -f $mountPath'/aftermount.sh' ]; then
			# Запуск заранее подготовленного скрипта, который будет
			# запускаться сразу после монтирования папки
			bash $mountPath'/aftermount.sh' $mountPath;
		    fi
		fi
	    fi
	fi
    done;
    # Перезапускаем веб-сервер
    service httpd restart
}
#================ UNMOUNTING ===================================================#
function umountFn {
    echo "Unmounting..."
    # Останавливаем веб-сервер
    service httpd stop
    for f in $sharedFolders; do
	mountPath=$mountPrefix$f$hn
	# Удаляем логи веб-сервера
	find $mountPath -type f -name httpd_"$f""$hn"_*.log -exec rm -f {} \;
	# Удаляем папки профилирования и трейсов
	rm -rf $mountPath/xd_profile_"$f""$hn"
	rm -rf $mountPath/xd_trace_"$f""$hn"
	# Выполняем заранее подготовленный стенарий, который должен
	# быть выполненым перед демонтированием папки
	if [ -f $mountPath'/beforeumount.sh' ]; then
	    bash $mountPath'/beforeumount.sh' $mountPath;
	fi
	# Демонтируем папку
	umount $mountPath
	# Подчищаем за собой
	if [[ $? -eq 0  ]]; then
	    rm -rf $mountPath 2> /dev/null
	    rm -f /etc/httpd/conf/sf/$f$hn.conf 2> /dev/null
	    echo "Unmounted and removed $f"
	    log umounted $mountPath
	else
	    echo "Not unmounted"
	fi
    done;
    # Запускаем веб-сервер
    service httpd start
}
#================ STATUS =======================================================#
function statusFn {
    com=0
    for f in $sharedFolders; do
	mountPath=$mountPrefix$f$hn
	if df | grep $mountPath &> /dev/null; then
	    com=`expr $com + 1`;
	    if [ $com -eq 1 ]; then
		echo List of mounted resources:
	    fi
	    df | grep $mountPath | egrep -o '\/.+$'
	fi
    done
    if [ $com -eq 0  ]; then
	echo No shared storage mounted
    fi
}
#===============================================================================#
if [ "$1" == "mount"  ]; then
    mountFn;
    exit 0
elif [ "$1" == "umount" ]; then
    umountFn;
    exit 0
elif [ "$1" == "status" ]; then
    statusFn;
    exit 0
else
    cat << EOF
    No arguments supplied
    -----------------------------------------------------------------------------
    Usage:
    -----------------------------------------------------------------------------
    Using with single argument one of:
	mount	: for mounting all shared folders under /var/www/html directory
	umount	: for unmounting all shared folders under /var/www/html directory
	status	: for checking mount status
    -----------------------------------------------------------------------------
    Using with two argument for mounting or unmounting single folder
    Example:
	vbox-sf mount foo	: will mount shared folder /media/sf_foo into /var/www/html/foo.domain.com
	vbox-sf umount foo	: will umount shared folder /media/sf_foo from /var/www/html/foo.domain.com
EOF
    exit 1
fi

exit 0


Что необходимо и как работает


  1. Необходимо установить на гостевеой машине веб-сервер (я выбрал apache).
  2. Для корректного монтирования расшаренных папок на гостевой ОС необходимо установить Guest Additions.
  3. Папку, которую мы монтируем следует назвать коротко, но уникально — это название будет поддоменом домена нашего сервера.
  4. В корень расшариваемой папки необходимо положить обязательно шаблон конфига виртуального хоста для веб-сервера.
    Приблизительный конфиг виртуального хоста для веб-сервера
    <VirtualHost *:80>
    	DocumentRoot /var/www/html/<%domain%>
    	ServerName <%domain%>
    	ServerAlias www.<%domain%>
    	DirectoryIndex index.php
    
    	<Directory /var/www/html/<%domain%>>
    		AllowOverride All
    		php_admin_value open_basedir /var/www/html/<%domain%>:/tmp:/usr/share:/var/lib
    	</Directory>
    
    	CustomLog	/var/www/html/<%domain%>/httpd_<%domain%>_access.log combined
    	ErrorLog	/var/www/html/<%domain%>/httpd_<%domain%>_error.log
    
    	php_admin_value xdebug.profiler_output_dir /var/www/html/<%domain%>/xd_profile_<%domain%>
    	php_admin_value xdebug.trace_output_dir /var/www/html/<%domain%>/xd_trace_<%domain%>
    </VirtualHost>

    Сам конфиг может изменяться, но основные моменты нужно сохранить: <%domain%> — маска, которая заменяется на домен для веб-приложения, файлы логов и папки для профилирования и трейсов (если необходимо). Все остальное по вкусу в зависимости от того, что необходимо в приложении.


  5. Папки необходимо расшаривать с автомаунтом и желательно с правом на запись в нее — мы же можем что-то и заливать через это наше приложение и потому файлы должны сохраняться. А кто-то может что-то и кеширует в файлы. Право на запись не помешает. Автомаунт важен — скрипт выбирает нужные папки по списку уже подмонтированных папок в /media/sf_* — именно поэтому папки должни монтироваться с автомаунтом. Должно выглядеть приблизительно так, как на скриншоте.
  6. На гостевой машине должен быть отключен SELinux. С включенным SELinux веб-сервер не видит, подмаунченых в /var/www/html/, папок — они маунтятся в контексте vbox, а не httpd. Я пока не нашел как это подправить и поэтому подпер костылем — отключил SELinux.
  7. Хостнейм у гостевой машины должен иметь вид домена. У меня это natty.nat и в итоге все веб-приложения, которые я маунчу в эту гостевую машину, будут иметь такой вид: [имя папки, которую расшариваем].[hostname]. например test.natty.nat. Лично мне удобно было вешать на такие домены.
  8. Необходимо создать папочку /etc/httpd/conf/sf,
    # mkdir -p /etc/httpd/conf/sf
    в которую будут складироваться конфиги виртуальных хостов веб-сервера. При этом в конце файла /etc/httpd/conf/httpd.conf необходимо инклудить все конфиги, которые мы будем складировать в вышеупомянутой папке:
    include "conf/sf/*.conf"


Если все хорошо, то теперь мы можем расшарить папку с нашим проектом на нашу виртуальную машину, запустить её и, выполнив следующую команду, получить готовое место для разработки:

# /path/to/vbox-sf.sh mount


Так мы подмаунтим все расшаренные папки. Если вторым аргументом указать имя нашей папки, то подмонтирует или демонтирует только её:

# /path/to/vbox-sf.sh mount test

# /path/to/vbox-sf.sh umount test


Демон


Но теперь было бы неплохо это дело как-то автоматизировать. Я выбрал путь демона и я считаю, что он будет более правильным, нежели руцями изменять /etc/rc.# файлы. Был написан следующий скрипт для /etc/init.d
Скрипт второй - демон - /etc/init.d/vboxsf
#!/bin/bash
#
# Author:	Dmitry Vapelnik
# Email:	dvapelnik@gmail.com

### BEGIN INIT INFO
# Required-Start: 	httpd mysqld vboxadd-service vboxadd
# Required-Stop:	httpd mysqld vboxadd-service vboxadd
# Default-Start:	3
# Default-Stop:		0 6
# Short-Description:	Mounting VirtualBox shared folders
# Description:		This file should be used to mount and umount 
#			VirtualBox shared folders
### END INIT INFO

# Get function from functions library
. /etc/init.d/functions

prog="VBoxSF"
lockfile='/var/lock/subsys/vboxsf'

# Start the service vbox-sf
start() {
#	initlog -c "echo -n Starting $prog server: "
	/root/bin/vbox-sf mount &> /dev/null && touch $lockfile
	success $"$prog: mounted"
	echo
}

# Restart the service vbox-sf
stop() {
#	initlog -c "echo -n Umounting $prog: "
	/root/bin/vbox-sf umount &> /dev/null && rm -f $lockfile
	success $"$prog: umounted"
	echo
}

status() {
	/root/bin/vbox-sf status
}

### main logic ###
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	status)
		status
		;;
	restart|reload|condrestart)
		stop
		start
		;;
	*)
		echo $"Usage: $0 {start|stop|restart|status}"
		exit 1
esac

exit 0


Этот скрипт необходимо положить в директорию /etc/init.d и назвать файл vboxsf. На самом деле здесь название файла некритично. Просто когда мы будем добавлять нового демона с помощью chkconfig, то нам необходимо будет указать имя этого файлика. Далее я буду использовать именно vboxsf.

Итак, мы добавили файл. Теперь нам необходимо перелинковать наш скрипт в /root/bin:

# mkdir -p /root/bin
# ln -s /root/scripts/vbox-sf.sh /root/bin/vbox-sf


Добавляем в chkconfig:

# chkconfig --add vboxsf


Проверяем все ли добавилось:

# chkconfig | grep vboxsf


Если все хорошо, нам должно показать, на каких уровнях будет запускаться наш скрипт.



В результате теперь мы можем просто использовать следующие команды:

# service vboxsf start
# service vboxsf stop
# service vboxsf restart
# service vboxsf status


Если нет, то смотрим что мы не так сделали. В принципе, на этом моменте все должно работать: монтироваться при запуске и демонтироваться перед выключением.

А теперь вкусняшки


Помните скрипты, которые выполняются после монтирования и перед демонтированием папки? Так вот, для более удобной работы я также разворачиваю базу из дампа в MySQL-сервер и перед тем, как произойдет демонтирование, сливаю базу обратно в дамп. Таким образом, мы имеем актуальный дамп базы после того, как выключим машину и имеем актуальную базу после включения машины.

Вот эти скрипты:
Скрипт третий - восстановление БД из дампа - aftermount.sh
#!/bin/sh

# Author:	Dmitry Vapelnik
# Email:	dvapelnik@gmail.com

if [ $# -eq 0  ]; then
    echo 'No arguments supplied';
    echo 'Exit';
    exit 0;
fi
######################################################
dbAdminUser='ourDbAdminLogin'
dbAdminPass='ourDbAdminPassword'

dbName='ourDbName'
dbUser='ourDbUser'
dbPass='ourDbPassword'
dbHost='localhost'
dbDump=$1'/db.sql'
######################################################

queryCreateUser="CREATE USER '$dbUser'@'$dbHost' IDENTIFIED BY '$dbPass';
CREATE DATABASE IF NOT EXISTS \`$dbName\`;
GRANT ALL PRIVILEGES ON \`$dbName\`.* TO '$dbUser'@'$dbHost';
FLUSH PRIVILEGES;"

echo Creating new user...
if mysql -u$dbAdminUser -p$dbAdminPass -e "$queryCreateUser"; then
    echo User added
    echo Using MySQL dump
    if mysql -u$dbAdminUser -p$dbAdminPass $dbName < $dbDump; then
	echo MySQL dump loaded into $dbName
    else
	echo MySQL dump not loaded
    fi
else
    echo Error: user not added exit
fi


Важно! Achtung! dbAdminUser и dbAdminPass — это логин и пароль администратора БД, который может создать/удалить пользователя, создать БД и залить в неё дамп.
ourDbName, ourDbUser и ourDbPassword — имя БД и логин и пароль пользователя MySQL, который используется в нашем монтируемом разрабатываемом веб-приложении.

Что делает этот скрипт:
  1. Создает пользователя;
  2. Создает БД;
  3. Заливает содержимое нашего дампа в эту базу


Что необходимо:

  1. Чтобы администратор БД мог добавить пользователя, создать БД и залить в неё наш дамп (я использую MySQL-пользователя root и некий короткий пароль — мне же никто не будет ломать мой сервер на VirtualBox);
  2. Дамп нашей БД должен лежать в корне расшариваемой папки в файле db.sql. Мы можем его назвать по-другому и положить в другое место, но тогда необходимо будет подправить и скрипт — это тоже не проблема при желании;
  3. Для соблюдения чистоты, ни создаваемого пользователя, ни БД не должно быть до разворачивания всего нашего дела.


Второй скрипт просто сохраняет содержимое нашей базы в файл, подчищает за собою юзера и удаляет БД.
Скрипт четвертый - сохранение БД в дамп - beforeumount.sh
#!/bin/sh

# Author:	Dmitry Vapelnik
# Email:	dvapelnik@gmail.com

if [ $# -eq 0  ]; then
    echo 'No arguments supplied';
    echo 'Exit';
    exit 0;
fi
######################################################
dbAdminUser='dbAdminUser'
dbAdminPass='dbAdminPass'

dbName='ourDbName'
dbUser='ourDbUser'
dbHost='localhost'
dbDump=$1'/db.sql'
######################################################

queryRemove="DROP DATABASE \`$dbName\`;
DROP USER '$dbUser'@'$dbHost';
FLUSH PRIVILEGES;"

echo Dumping MySQL DB into file..

if mysqldump -u$dbAdminUser -p$dbAdminPass $dbName > $dbDump; then
    echo DB dumped into file
    echo Removing user and database
    if mysql -u$dbAdminUser -p$dbAdminPass -e "$queryRemove"; then
	echo User and DB was removed
    else
	echo Error on removing
    fi
fi

Настройки как и в предыдущем скрипте. На этом этапе все должно быть прозрачно.

После всех этих манипуляций мы получаем следующее: у нас есть виртуальный сервер, работающий под VirtualBox; после того, как мы его включили, он автоматом маунтит наши папки, создает пользователя, базу данных в MySQL, заливает в неё наш заранее подготовленный дамп — можно работать — логи лежат фактически у нас на машине, файли профлирования и трейсы тоже у нас на машине; по завершении работы отключаем сервер: логи удаляются, файлы профилирования и трейсы удаляются вместе с папкой, содержимое базы данных дампится обратно в наш файл, папки демонтируются и машина выключается. Фактически, сервер у нас играет роль некоего суррогата или донора — на нем ничего окончательно не сохраняется и не валяется, а он только воспроизводит то, что мы ему подкидываем.

Приятный и местами полезный бонус: мы можем настроить несколько серверов с разными версиями ПО и одновременно проверять, как работает наше веб-приложение на каждой из версий php, MySQL, Apache. Логи, трейсы и файлы профилирования будут лежать в отдельных файлах в зависимости от имени домена, чтобы не мешать все в кучу.

При необходимости можно навесить других вкусняшек и удобностей, но это уже по вкусу и потребностям каждого разработчика отдельно. Все, что нужно, пихаем в скрипты, которые выполняются после монтирования и перед демонтированием.

Да, ещё важная деталь. Чтобы не прописывать весь зоопарк поддоменов, которые могут использоваться для разработки, необходимо установить на серверной машине (на машине, на которой мы ведем разработку и где установлен VirtualBox, у меня это ноутбук) Dnsmasq — это легковесный DNS, DHCP, TFTP (BOOTP, PXE) сервер. Настраивается он донельзя противного просто. Очищенный мой конфиг выглядит так (да, у меня три машины: 5.3, 5.4, 5.5):

$ cat /etc/dnsmasq.conf | egrep -v "(^#.*|^$)"
listen-address=127.0.0.1
address=/natty.nat/192.168.191.160
address=/ketty.nat/192.168.191.161
address=/betsy.nat/192.168.191.162


Таким образом, все поддомены этих доменов будут направляться на указанные IP-адреса.

Еще может кому будет полезен кусок /etc/php.ini, который отвечает за XDebug.
Кусок от /etc/php.ini
; этот путь может быть другим - смотрим куда установится XDebug
zend_extension="xdebug.so"
xdebug.cli_color=1
xdebug.remote_enable=true
xdebug.remote_host="192.168.191.1"
xdebug.remote_port=9000
xdebug.remote_handler="dbgp"
xdebug.remote_connect_back=1
; Profiler
xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 1
xdebug.profiler_append = 0
; Trace options
xdebug.collect_includes = 1
xdebug.collect_params = 4
xdebug.collect_vars = 0
xdebug.dump.REQUEST = *
xdebug.dump.SESSION = *
;xdebug.dump.SERVER = REMOTE_ADDR,REQUEST_METHOD
xdebug.dump.SERVER = *
xdebug.dump_globals = 1
xdebug.dump_once = 1
xdebug.dump_undefined = 0
xdebug.show_mem_delta = Off
;xdebug.file_link_format = ''
xdebug.manual_url = http://www.php.net
xdebug.show_exception_trace = 1
xdebug.show_local_vars = 1
xdebug.show_mem_delta = 1
; Traces
xdebug.auto_trace = 0
xdebug.collect_assignments = 1
xdebug.collect_return = 1
xdebug.trace_enable_trigger = 1
; 0 for parsing
; 1 human readable
xdebug.trace_format = 1
xdebug.trace_options = 0
xdebug.trace_output_name = trace.%c


Если кто не знает, под огнелис есть удобное расширение для работы с XDebug — The easiest Xdebug, которое позволяет включать/отключаться остановку на брейкпоинтах, профилирование и трейс.

Я все создавал в сети 192.168.191.0/24 и потом, мои IP из этой подсети. Если у вас другая подсеть — изменяйтесь как вам удобно.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 32

    0
    По долгу работы приходится иметь дело в VirtualBox на борту с Linux. Вы случайно не подскажите как можно автоматизировать создание снапшотов гостевой оси?
      +8
      Virtualbox + Vagrant + ansible|chef|puppet
        +3
        Смотрите в сторону команды VBoxManage
          0
          Спасибо! Идеально для меня подходит.
        0
        Как альтернатива, для изолированного рабочего окружения есть bitnami.
          +2
          Не проще это будет через docker делать?
            0
            Возможно, знакомлюсь с ним
              0
              Также советую ознакомиться с Docker. Тем более если у вас хостовая машина на Linux.

              Итак, плюсы:
              1) Если изменения в контейнере не закоммитить то они не сохраняются — стало быть нет нужды в очистке мусора после работы с виртуалкой
              2) Гибкая система с наслаиванием образов контейнеров друг на друга — есть возможность пилить минимально отличающиеся конфигурации на базе одного контейнера
              3) Он просто работает быстрее и стартует практически моментально из-за отсутствия оверхеда на виртуализацию железа

              Недавно решал для себя схожую задачу, получилось вот так: hamdeew.ru/page/lokalnyj-vebserver-bez-boli-s-docker
              Также скидываю дамп БД при остановке контейнера и также годом ранее городил огород из костылей к VirtualBox =)
                0
                да, еще раз спасибо за наводку на docker. я его уже поковырял немного и полностью согласен, что на нем это намного удобнее делать и пилю скрипты уже в сторону docker. в конце концов, он меньше ресурсов выедает. но есть несколько камней, которые я опишу, но сначала вопрос:
                в процессе однакомления с docker я выкачал образ CentOS (в пачке я получил три образа: centos5, centos6, centos7 — остановился на шестом)
                # docker images
                REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
                centos              centos5             5a1ebaa356ff        5 days ago          484 MB
                centos              centos7             70214e5d0a90        9 days ago          224 MB
                centos              latest              70214e5d0a90        9 days ago          224 MB
                centos              centos6             68eb857ffb51        9 days ago          212.7 MB
                

                далее я запускаю контейнер и вижу следующее:
                # docker ps
                CONTAINER ID        IMAGE               COMMAND ....
                e8e254b40b74        centos:centos6      "/bin/bash" ....
                

                я что-то там установлю, сделаю в этом контейнере. выключу-включу его же незакоммиченный через start и вижу все то, что я устанавливал и изменял. это плохой тон использовать незакоммиченные контейнеры для работы? нужно для при очерезной потребности запускать (run) контейнер для работы с ним?.. хотя да, если мы пробрасываем в него разные проекты, то должны и перезапускать контейнер (stop, rm, run) с новым проектом. хотя, может, я до конца ещё не вникся философией docker
                но все же мне хотелось бы иметь следующее:
                1. Запустить контейнер (start)
                2. Выполнить скрипт с одним-двумя-тремя параметрометрами (папка с хост-машины прокидывается в docker, разворачивается БД)
                3. Работаем с проектом
                4. Выполнить скрипт с одним-двумя-тремя параметрометрами (БД дампится обратно и дизмаунтится папка)

                итак, камни:
                1. Пока не встретил нигде возможности удаленно с хост-машины выполнить скрипт в контейнере (да, можно выполнять его при запуске контейнера (run), но пока не связал все в единый скрипт, чтобы его выполнить)
                2. Можно в контейнере поднимать sshd и с хост-машины выполняться скрипт в контейнере
                  # ssh root@container 'service httpd restart'
                  

                  но мне кажется это неправильным идеологически в разрезе docker. К тому же, постоянно изменятся IP контейнера — как минимум, будет спрашивать прием server fingerprint — что тоже не особо удобно. Прописывать нужные IP и относить их к конкретному домену в dnsmasq.conf я уже научился.

                больше камней не припомню — не натолкнулся ещё
                в будущем хотелось бы это все дело поднять именно на docker — меня соблазнила скорость его работы и легковесность
                  0
                  По идее активно коммитить в контейнер не следует — это всего лишь окружение для запуска ваших проектов которое должно оставаться неизменным.
                  Вот краткий рецепт первоначальной настройки:
                  1) Делаем docker pull нужного образа (чтобы не скачивать всю линейку можно указать конкретный релиз)
                  2) Запускаем через docker run -t -i <image_name> /bin/bash и попадаем в консоль вашего контейнера.
                  3) Там все настраиваем как надо и затем запускаем второй терминал на хост машине, там набираем docker ps и в итоге получаем container_id, затем полученный id применяем вот так docker commit <container_id> <my_image_name>
                  4) В первом терминале просто выходим из контейнера по Ctrl+D, он автоматически останавливается.

                  Затем работаем вот так (привожу мой вариант):
                  1) Запускаем наш получившийся контейнер через docker run -v /home/rail/www/project/:/var/www/srv/ -p 80:80 -t -i rhamdeew/lamp /bin/bash
                  2) Там запускаем необходимые сервисы (для удобства bash-скриптом)
                  3) Кодим
                  4) Запускаем stop.sh и после окончания его работы выходим по Ctrl+D

                  Кстати посмотреть все доступные контейнеры на вашей машине можно так — docker ps -a

                  P.S. Совсем забыл — полученный в итоге готовый для работы контейнер можно сохраниить в репозитории hub.docker.com дабы иметь возможность оперативно его восстановить оттуда либо поделиться с друзьями.
                    0
                    спасибо за подсказки и информацию
                    я поковырял ваш контейнер, ваши скрипты start/stop и разобрался как у вас оно работает. на сколько я понял, то вы пробрасываете папку проекта в контейнер (-v). я только вот не совсем разобрался как вы решили следующую проблему: папку с расшариваю (-v /path/to/src:/path/to/dst), но апач, запущенный под apache:apache не может использовать и писать в файлы, которые были расшарены в контейнер. Владелец и группа папки/файлов — 1000. на сколько я понимаю, то это UID и GID с хост-машины. Далее, если я изменю владельца: группу на файлы с контейнера, то изменятся эти данные и в на хост-машине, но на UID:GID пользователя с контейнера.
                    Можно ли это как-либо причесать чтобы при расшаривании в контейнере файлы принадлежали определенному пользователю (например, апачу для удобной работы с ними) и новые файлы, залитые в контейнер посредством апача (аплоад файла например) на хост машине принадлежали текущему пользователю на хост-машине?
                    разбираюсь и приходят новые мысли как мне это все расширить и реализовать
                      0
                      Проблему с правами доступа решил не самым элегантным путем, но это все же не продакшн. Так что думаю можно =)

                      1) Создал в контейнере такого же обыкновенного пользователя useradd rail и его UID/GUID также стали равны 1000
                      2) Подправил запуск Apache под этим пользователем vim /etc/apache2/envvars, там параметры APACHE_RUN_USER и APACHE_RUN_GROUP выставил rail

                      Вот собственно и все =)
                      0
                      Дополню, что можно дать имя контейнеру и не надо будет колдовать с id`ишникам, плюсом будет возможность связывать контейнеры между собой и обращаться по именам контейнеров внутри контейнеров.
              0
              Все очень красиво, можно даже использовать…
              Только немножко упростить.
              1. Создать локальную сеть из виртуальной машины (или из машин).
              2. Соответственно настроить hosts на свои develop сайты (из виртуальной машины).
              3. Использовать sshfs
              В заключение — правильно настроить сервер на виртуалке для быстрого разворачивания любого сайта, а не издеваться над /var/www

              mkdir -p /root/bin
              — вообще умиляет…
                0
                1. Подразумевается, что локальная сеть с виртуальной машиной есть. Используется HostOnly виртуальная сетевая карта и через неё осуществляется доступ с основной машины (ноут) к виртуальной — в данном случае сеть 192.168.191.0/24. Это должно быть понятно ибо в любом случае нужно как-то к гостевой машине по ssh, http и/или использования удаленной работы с mysql сервером
                2. Я так понимаю, что Вы предлагаете иметь доступ с виртуальной машины на продакшн-хост сайта? Для чего? Деплой можно реализовать с машины, где ведется разработка (я не знаю как правильно её назвать в этом контексте — ноут). PhpStorm позволяет синхронизацию с удаленным сервером, выгрузку измененных файло после успешного коммита изменений в git, можно настроить деплой через хуки гита — деплой можно придумать какой-угодно. Я не вижу упрощения в данном случае
                3. Упросить путем использования sshfs? Если я Вас верно пониаю, то вы предлагаете с виртуальной машины стучаться в ноут, брать там нужную папочку и монтировать её по sshfs в вирутальную машину? Если верно, то нам придется под каждую папку руцями прописывать путь к требуемой папке. Папки проектов могут лежать на ноуте где-попало — нам ничего не запрещает один проект положить на декстопе, второй в /tmp, третий в ~/Downloads и так далее. Есть ли идея реализации универсального монтирования этих папочек в виртуальную машину? Мне в голову пока ничего не приходит. В моем случае все монтируемые папки лежат в одном месте /media/sf_*. Изначально я выбирал непустые папки из этой директории и монтировал. Но потом использовал непосредственно список подмонтированных папок, что я считаю более правильным. В таком случае нам вообще не нужно лгиниться в виртуальную машину чтобы настроить монтирование нужной папки. Мы просто кладем конфиг для веб-сервера в папку проекта, расшариваем папку в виртуальную машину и запускаем ей. Все! Больше мы ничего не делаем.
                4. Как правильно настроить сервер, я думаю, что имеемтся в виду веб-сервер, для быстрого разворачивания любого сайта? DocumentRoot может быть как в корне, так и в директории www/, могут быть специальные настройки окружения (на некоторых проектах я использую настройку через SetEnv для статуса приложения: дебаг или нет. Я считаю, что это удобно сделать в настройках виртуального хоста веб-сервера для каждого проета.
                5. Чем
                  # mkdir -p /root/bin
                  

                  не угодил? после установки этой папки у рута дома нет. А может у кого и есть. В используемом мной дистрибутиве её не было.

                Целью ставилось создание независимого скрипта, который бы дела все за нас, а от нас требовалось бы только подготовить конфиг для веб-сервера и положить дамп базы если это нужно.
                0
                Вы используете автоматически подключенные папки. В скрипте вынуждены их же искать, чтобы потом их еще раз примонтировать.
                Блок схема этой логики выглядела бы как минимум странно и неэффективно.
                Куда проще было бы работать с заранее известным расположением «папочек» и «файликов», использовав для этого например nfs.
                PS.
                Хостнейм у гостевой машины должен иметь вид домена, и называется это FQDN.

                  0
                  Да, можно было бы использовать, но как я писал выше, это было бы не настолько юзабельно и пришлось бы вручную прописывать путь для каждого проекта (папки)
                  За FQDN спасибо
                  +5
                  статью подробно не читал, но вроде как vagrant то же самое делает?
                    +1
                    тот же самый вопрос — в чем лучше вагранта?
                    +1
                    Если хост система основана на Linux, то лучше использовать docker. Как минимум не будет затрат на еще одну работающую ОС. Как максимум, можно будет поднимать докер контейнеры на сервере, гарантировав однообразность окружения продакшена и двелопминга.
                      –1
                      1. ok, невнимательно посмотрел
                      2 и 3. Я имел ввиду, что раз уж вы на VM разработку делаете, то все там же и лежит. Поэтому sshfs. Кстати, «стучаться» при соответствующей настройке совсем нет надобности.
                      Если же монтировать папки с ноута в VM, то, если я правильно помню, VM имеет стандартные средства совместного использования папок с автомонтированием.

                      PHPStorm не использую. Пользуюсь Sublime.
                      И, в заключение, я так понял, все это в контексте Windows?
                      Для себя давно сделал выводы и использую на компьютерах Linux, уже давно.
                      Там этих проблем нет.
                      На ноуте стоит lighttpd, я его и в работе использую.
                      С остальными компонентами — Mysql, Redis, git, тоже проблем нет :) Плюс любая автоматизация :)
                      В результате старт проекта — создание хоста -> инициализация проекта (git bitbucket)
                      Поэтому практически отпала необходимость в VM при разработке.
                      VM только, если что-то хочется попробовать неординарное, или смоделировать сеть.

                      По-поводу /root/bin — есть стандартная организация файловой системы. И для ваших целей есть каталог /usr/local/bin

                        0
                        Хост-машина тоже под Linux, но проблема в версиях ПО, прежде всего PHP. Изначально это делалось для того, чтобы иметь возможность разрабатывать на разных версиях PHP. Есть проект, который жестко требует php5.3 и переписывать его, как минимум, на php5.4 никто точно не будет, а допиливать его нужно. Остальные проекты требуют, как минимум, php5.4. php5.4 для тестирования и php5.6 для ознакомления. Поднять этот весь зоопарк на одной машине, на хосте, и настроить динамическую смену версий для каждого проекта и к тому же, чтобы одновременно один и тот же проект запустить на нескольких версиях php невозможно. Да, несколько версий php можно поднять и настроить, но это ещё те танцы с бубном. Лично мне не хочется загаживать рабочую ОС (да тот же Linux) левым софтом типа четырех версий php, установленным с танцами.
                        В качестве удаленного репозитория я использую связку Redmine+Gitolite на удаленном сервере.
                        +1
                        Расскажите автору про Docker %-)
                          +3
                          не знаю где тут лень, с vagrant все значительно проще )))
                            –2
                            Vagrant у меня не завелся с конфигом от puphpet.com — валился httpd и ни в какую
                              +2
                              советую пройти их мануал на офф-сайте — docs.vagrantup.com/v2/getting-started/index.html. Классная вещь.
                                +1
                                Спасибо, снова вернусь туда и снова почитаю ман )
                                0
                                У меня тоже пару раз их конфиг валился. Но в итоге все равно в большинстве случаев все загружалось без сбоев. Можно еще разок попробовать )
                              0
                              Добавлю, что часто для рабочих групп единая среда — суровая необходимость. А чтобы компенсировать тормоза виртуалки, ставьте ее на SSD. С ним даже Windows-кластер из двух виртуальных машин летает. И ядер побольше отдайте. Будете приятно удивлены, видя на что способен ваш компьютер…
                                0
                                Когда мне надоело сидеть на общих девсредах на рабочем сервере с одной базой на всех и другими разделяемыми ресурсами, я создал полноценный инстанс в виртуалке под виртуалбоксом. Скриптом запускаю виртуалку, тут же монтирование папки в хостовую ОС для работы под эклипсом (виртуальная девреда для экономии ресурсов без гуя), и шел. Аналогичный скрипт закрытия. Гемор был с подъемом всех частей веб-приложения на одной виртуальной машине. В реальном инстансе разные роли разделяются на разные машины: приходилось вникать и решать конфликты. Но в итоге решение получилось: полностью автономная работа даже без интернета, при необходимости (или с медленным интернетом, при котором крайне некомфортно работать по сети из-за большого пинга). До сих пор отлично работается удаленно и независимо от инфраструктуры работодателя (особенно после перехода на гит).
                                  0
                                  Я видимо совсем ленивый, мне Wampserver-a достаточно
                                    0
                                    кто-нибудь подскажет как решить проблему с docker?
                                    1. запускаю контейнер с --privileged — в контейнере не запускается mysql-server
                                      результат
                                      root@b1d8a93c420a:/# service mysql start
                                      /usr/sbin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: Permission denied
                                      


                                    2. запускаю контейнер без --privileged — не работает sshfs
                                      результат
                                      root@5d61518c125f:/# sshfs dvapelnik@172.17.42.1:/home/dvapelnik/tmp /mnt -o uid=33,gid=33
                                      fuse: failed to open /dev/fuse: Operation not permitted
                                      



                                    sshfs нужен для корректного монтирования папки с хост-машины — при прокидывании папки с помощью run -v не совсем корректно идет работа с правами на содержимое этой папки
                                    как вариант — не запуска mysql-server в контейнере, а использовать mysq-server на хост-машине, но тогда для прозрачности работы с ним через localhost было бы неплохо сфорвардить порт 3306 с контейнера в хост-машину, а это не удается

                                    Only users with full accounts can post comments. Log in, please.