Commit e590e2ae authored by atnartur's avatar atnartur

+ content

parents
# Docker docs
Документация по Docker-инфраструктуре от Артура.
![](https://gitlab.com/atnartur/docker-docs/raw/6bc2396e800ee42182d2dcd9e99bc881eb2f56aa/images/docker.png)
[Docker](https://ru.wikipedia.org/wiki/Docker) — программное обеспечение для автоматизации развёртывания и управления приложениями в среде виртуализации на уровне операционной системы, например LXC.
[LXC (англ. Linux Containers)](https://ru.wikipedia.org/wiki/LXC) — система виртуализации на уровне операционной системы для запуска нескольких изолированных экземпляров операционной системы Linux на одном узле. LXC не использует виртуальные машины, а создает виртуальное окружение с собственным пространством процессов и сетевым стеком. Все экземпляры LXC используют один экземпляр ядра операционной системы.
- [Официальный сайт Docker](http://docker.com)
- [Docker Hub - репозиторий образов Docker](http://hub.docker.com)
- [Избушка на docker-ножках или объяснение Docker на примере домов](http://atnartur.ru/posts/2016/docker-house/)
- [Митап сообщества CruelIT с подробным объяснением основ работы docker](https://github.com/CruelIT/meetups/tree/master/2017-02-22%20Docker)
\ No newline at end of file
# Сборка производится с помощью этого контейнера
image: atnartur/docker:1.12.2
# порядок выполнения задач
stages:
- build
- deploy
# перед выполнением
before_script:
# авторизуемся в docker registry
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com
# сборка образа
docker-build:
stage: build
script:
- docker build -t registry.gitlab.com/USERNAME/REPONAME -f docker/Dockerfile .
- docker push registry.gitlab.com/USERNAME/REPONAME
tags:
# теги позволяют характирезовать gitlab-runner`ы. Таким образом, этот билд будет запускаться
# только на раннерах, которые имеют тег docker
- docker
run_prod:
stage: deploy
script:
- docker pull registry.gitlab.com/USERNAME/REPONAME
- docker-compose -f docker-compose.prod.yml -p projectname_prod stop
- docker-compose -f docker-compose.prod.yml -p projectname_prod rm -f
- docker-compose -f docker-compose.prod.yml -p projectname_prod up -d --force-recreate
# удаление образов, которые не принадлежат ни одному контейнеру (очистка образов)
- docker rmi $(docker images -q -f dangling=true) || echo 1
only:
- master
tags:
- docker
# проект скорее всего должен разворачиваться на своем сервере. Здесь нужно указать тег раннера, который
# запускается на сервере проекта
- project_server_tag
# Gitlab CI
Типовой конфиг Gitlab CI для сборки проекта в Docker (примерная архитектура проекта объяснена в папке "Перенос проекта Docker") находится в `.gitlab-ci.yml`.
Этот файл нужно положить в корень проекта. В таком случае CI будет читать его при каждом коммите и выполнять команды оттуда при необходимости. Файл снабжен подробными пояснениями.
Согласно указанной конфигурации CI для сборок используется образ `atnartur/docker` ([Docker hub](https://hub.docker.com/r/atnartur/docker/) / [Github](https://github.com/atnartur/docker-image)). Образ базируется на [debian](hub.docker.com/r/_/debian) и содержит `docker` и `docker-compose`. Скрипты установки этих программ взяты из официальных репозиториев.
# Команда запуска gitlab-runner в режиме docker-in-docker
запускаем раннер
```
docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.gitlab-runner:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
```
регистрация раннера
```
docker exec -ti gitlab-runner gitlab-runner register -n \
--url https://gitlab.com/ci \
--registration-token TOKEN \
--executor docker \
--description "name" \
--docker-image "atnartur/docker:latest" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock
```
запуск сервиса
`docker exec -ti gitlab-runner gitlab-runner start`
\ No newline at end of file
# Названия контейнеров в проекте и варианты образов
Образы можно использовать другие, но я рекомендую использовать эти. Если проект требует особенных настроек, то можно собрать все эти обраты вручную.
- web - nginx
+ [nginx:latest](https://hub.docker.com/_/nginx/) - официальный
- php - php
+ [php](https://hub.docker.com/_/php/) - официальный
+ [atnartur/php](https://hub.docker.com/r/atnartur/php/) - мои сборки. Тега `latest` нет, поэтому нужно указывать тег вручную. Названия тегов есть на Docker Hub на [этой странице](https://hub.docker.com/r/atnartur/php/tags/). Для сборки собственных образов Docker с установкой своих расширений можно использовать [мои Dockerfile](https://github.com/atnartur/php-images) как пример
- db - mysq / percona
+ [percona](https://hub.docker.com/_/percona/) - percona - улучшенный форк mysql
+ [postgres](https://hub.docker.com/r/_/postgres/) - postgres
+ [postgis](https://hub.docker.com/r/mdillon/postgis) - postgres с установленным географическим расширением postgis
- data - контейнер с данными проекта. Там происходит сборка всех frontend-файлов, установка зависимостей
+ для легковесности контейнеры data обычно собирают на основе образа [alpine](https://hub.docker.com/r/_/alpine/) - об этом подробнее далее.
Контейнеры в проекте связываются через docker-compose и доступны по их короткому названию. Пример: при связывании контейнеров `php` и `db` внутри `php` к базе данных надо подключаться по хостнейму `db`.
Еще некоторые полезные образы:
- [donnex/pgweb](https://hub.docker.com/r/donnex/pgweb) - легковесная админка postgres
- [phpmyadmin/phpmyadmin](https://hub.docker.com/r/phpmyadmin/phpmyadmin/)
- [node](https://hub.docker.com/r/_/node/)
# Настройка nginx
Конфигурация nginx лежит в папке `docker/nginx`. Пример конфигурации лежит в папке `files/nginx`. Этот пример предназначен для использования с проектом на PHP с фреймворком Phalcon.
Основная задача контейнера с веб-сервером: обрабатывать веб-запросы и при неободимости перенаправлять часть из них на другие контейнеры (php/nodejs/...)
# Сборка контейнера data
Создаем файл `Dockerfile` в папке `docker`. Это файл с инструкциями для сборки контейнера data для проекта. Для легковесности контейнеры data обычно собирают на основе образа [alpine](https://hub.docker.com/r/_/alpine/).
Его примерное содержание находится в `files/Dockerfile`.
Там происходит:
1. Копирование папки с конфигурациями nginx в папку контейнера
2. Копирование файлов проекта в контейнер
3. Копирование конфигурации, зависящей от сервера, на ее место
4. Установка зависимостей npm, bower, сборка через gulp
5. Удаление папки docker из контейнера, удаление всех docker-конфигов - этого всего не должно быть в контейнере
6. Установка прав на утилитку `wait-for-it` (помогает контейнеру php ждать, пока произойдет запуск БД)
Этот Dockerfile так же лежит в `files/Dockerfile`. Контейнер data наследуется от образа alpine - очень маленький линукс дистрибутив весом всего лишь в 5МБ.
**Команда сборки образа** (запускается в корневой папке проекта)
```
docker build -t registry.gitlab.com/USERNAME/REPONAME -f docker/Dockerfile .
```
Ключ `-t` отвечает за название тега. Тег `registry.gitlab.com/USERNAME/REPONAME` создает образ, который можно будет отправить в Gitlab registry (хранилище Docker-образов в Gitlab) в репозиторий `USERNAME/REPONAME`.
Ключ `-f` помогает найти Dockerfile для сборки образа.
Подробнее про сборку контейнера можно прочитать в официальной документации: [о Dockerfile](https://docs.docker.com/engine/reference/builder/), [о `docker build`](https://docs.docker.com/engine/reference/commandline/build/)
После того, как образ будет готов, его можно отправить в Gitlab registry следующей командой:
```
docker push registry.gitlab.com/USERNAME/REPONAME
```
Скачивание образа:
```
docker pull registry.gitlab.com/USERNAME/REPONAME
```
На этом сборка контейнера с кодом проекта завершена.
\ No newline at end of file
# docker-compose
На предыдущих шагах мы поняли, что у нас есть контейнеры (к примеру) `nginx`, `php`, `percona` и есть контейнер `data` с кодом нашего проекта. Но все эти ребята живут поотдельности, и их надо как-то связать. Этим как раз и занимается docker-compose. Конфигурация для docker-compose лежит в файле `docker-compose.yml`.
## Конфигурационный файл
Примерное содержание этого файла лежит в `files/docker-compose.yml`. Этот файл снабжен подробными комментариями.
Для того, чтобы понять, что контейнер базы данных запустился полностью, используется скрипт `wait-for-it.sh`. Он ждет, пока появится возможность сделать обмениваться сетевыми пакетами с некоторым хостнеймом на определенном порту, и когда эта возможность появляется, он завершает свое выполнение. После этого выполняются команды, которым нужен был тот сервис, который мы ожидали.
## Запуск
Для того, чтобы запустить проект, нужно перейти в папку проекта и написать:
```
docker-compose up
```
Если в текущей папке есть файл `docker-compose.yml`, то согласно его конфигу будет поднят проект.
Подробнее о настройке docker-compose в [официальной документации](https://docs.docker.com/compose/compose-file/)
\ No newline at end of file
# Production config
Production конфигурация реализовывается как отдельный конфигурационный файл docker-compose. Все настройки контейнеров должны быть изначально такими, как будто они запускатся в production (возможны лишь небольшие отличия). Образы никак не должны меняться.
## Конфигурационный файл
И так, в `files/docker-compose.prod.yml` содержится пример production конфигурации, снабженный многочисленными комментариями.
Во время настройки проброса портов нужно помнить о том, что кроме этого проекта на сервере могут быть запущены еще и другие, поэтому пробрасывать порты внутренних сервисов (типа базы данных, redis...) не стоит. Хорошо, когда проект в результате пробрасывает только порт веб-сервера.
## Запуск
```
docker-compose -f docker-compose.prod.yml up -d
```
- `-f` - говорим новый путь до файла
- `-d` - detached - запуск в фоновом режиме
После запуска команды будут выведены имена только что запущенных контейнеров.
# docker-nginx
В классических конфигурациях на сервере обычно один веб-сервер, который слушает 80 и 443 порт и перенаправляет соединения с хостнеймов на определенные папочки согласно конфигурациям. Так как docker-архитектура предполагает использование своих веб-серверов в каждом проекте, значит нужен какой-то один внешний веб-сервер, который будет собирать все запросы извне и разбираться с тем, куда перенаправить каждый из них.
Такой nginx будет называться в дальнейшем **фронтовым nginx** или docker-nginx.
## Принцип работы
docker-nginx - специально собранный контейнер nginx, который следит за изменением списка запущенных контейнеров. Если в этом списке в сети `web` появляется контейнер, который имеет переменную окружения `VIRTUAL_HOST` и пробрасывает порт наружу, значит этот контейнер прикрепляется к домену из `VIRTUAL_HOST`, а все запросы будут преброшены на тот порт, который был проброшен.
_Оригинальный [исходный код](https://github.com/jwilder/nginx-proxy) этого проекта написан [jwilder](https://github.com/jwilder). [Версия от Артур](https://github.com/atnartur/nginx-proxy), о которой как раз и идет здесь речь._
## Настройка
Для того, чтобы все заработало, в docker-compose файле проекта нужно сделать следующие настройки (они были сделаны в `docker-compose.prod.yml`)
```yml
services:
web:
image: nginx:latest
ports:
- 80 # пробрасываем 80 порт
networks:
- web # прикрепляемся к сети web
- project_network
environment:
VIRTUAL_HOST: example.com # указываем хост, на который должен проброситься данный сервис
```
После запуска этого проекта docker-nginx словит этот контейнер и подцепит адрес.
Конечно же, для работы всей системы на сервере должен быть поднят сам docker-nginx. Это делается с помощью команды `docker-compose up -d` в папке проекта docker-nginx.
## Углубленная настройка
О том, как добавить дополнительные настройки к адресам у фронтового nginx, можно прочитать в README [этого проекта](https://github.com/atnartur/nginx-proxy)
# Summary
И так, соберем воедино все то, что произошло только что, и поймем, что же все-таки нужно сделать для того, чтобы запустить проект в docker.
## Dev окружение
1. Взять `docker-compose.yml`, взять базовые образы, сделать сделать настройку переменных окружения у контейнеров (если это необходимо)
2. Скопировать конфигурации для контейнеров (например, папку для `nginx`)
3. Создать `Dockerfile` с инструкциями для сборки data-контейнера проекта
4. Собрать и запушить этот контейнер в Docker-registry
5. Выполнить `docker-compose up` и проверить работу проекта
## Prod окружение
Для настройки prod окружения нужно сначала настроить dev окружение. Если dev-версия уже работает, продолжаем:
1. Создаем `docker-compose.prod.yml` на основе `docker-compose.yml`
2. Пересобираем data-контейнер и проверяем работу работу prod-версии. Исправляем найденные ошибки, если они есть.
# Перенос проекта в Docker
## Вступление
В корне проекта создаем папку `docker`. В ней будут храниться файлы, необходимые для сборки контейнеров и запуска проекта в среде Docker.
- nginx - папка с конфигурацией nginx
- Dockerfile - Dockerfile для сборки контейнера data
- config server prod (может назваться по разному в зависимости от проекта) - production конфигурация
- остальные файлы, необходимые для сборки и запуска проекта в среде Docker.
В корне папки проекта также будут лежать два файла: `docker-compose.yml` и `docker-compose.prod.yml`.
# берем базовый образ
FROM alpine:latest
# копируем конфиругацию nginx, чтобы потом прокинуть ее в соответствующий контейнер
COPY ./docker/nginx /etc/nginx
# ставим все необходимое для сборки
RUN apk add --no-cache \
nodejs bash git \
php5 php5-phar php5-json php5-ctype php5-openssl
# ставим утилиты для сборки и установки зависимостей на фронтенде
RUN npm i -q -g bower gulp
# создаем папку для проекта в контейнере
RUN mkdir /srv -p && mkdir /srv/www/ -p && mkdir /srv/www/app -p
# копируем файл со списком зависимостей composer
COPY ./composer.phar /srv/www/app
COPY ./composer.json /srv/www/app
# переходим в папку проекта
WORKDIR /srv/www/app
# устанавливаем зависимости composer
RUN php -d memory_limit=1024M composer.phar install --no-interaction --ignore-platform-reqs -o
# копируем файл с зависимостями npm и ставим их
COPY ./package.json /srv/www/app
RUN npm i -q --max_old_space_size=512
# то же самое с bower
COPY ./bower.json /srv/www/app
COPY ./.bowerrc /srv/www/app
RUN bower i --allow-root
# копируем остальной код проекта
COPY . /srv/www/app
# сборка фронтенда
RUN gulp -e production
# последние штрихи
RUN cp ./docker/config_server.prod.json /srv/www/app/app/config/server.json && \
chmod +x ./wait-for-it.sh && \
chmod +x ./php_start.sh && \
rm docker -r && \
rm public/js -r && \
rm public/styles -r
CMD /bin/true
\ No newline at end of file
# перед разбором этого файла нужно разобрать docker-compose.yml, который содержит
# очень много комментариев. Здесь будут даны комментарии только тому, что поменялось
# относительно docker-compose.yml
version: '2'
services:
web:
image: nginx:latest
# пробрасываем 80 порт наружу, не указывая конечный порт для того, чтобы docker-nginx
# понял, что нужно прицепить этот контейнер к хостнейму, указанному ниже (подробнее
# в разделе "docker-nginx")
ports:
- 80
volumes_from:
- data
depends_on:
- php
restart: always # в случае неожиданного падения контейнера, он перезапустится
networks:
# общая сеть для всех web-проектов - помогает привязать проект к хостнейму (об этом
# подробнее в разделе "docker-nginx")
- web
# сеть проекта
- project
environment:
# говорит, к какому хостнейму должен быть привязан этот контейнер. Можно указать несколько
# через запятую. Контейнер будет привязан с настройками по умолчанию, которые могут не
# удовлетворять потребностям проекта. Обо всем этом далее в разделе "docker-nginx".
VIRTUAL_HOST: project.ru
php:
image: atnartur/php:7.0.11-fpm-phalcon3.0.1
working_dir: /srv/www/app
command: sh -c "./wait-for-it.sh db:3306 && php vendor/bin/phinx migrate -e docker && php-fpm -RF"
depends_on:
- db
volumes_from:
- data
restart: always
networks:
- project
volumes:
- system-tmp:/tmp
# прокидываем папку с логами в папку в файловой системе
- /home/serveruser/project_prod_logs:/var/log/project
db:
image: mdillon/postgis:9.6
environment:
POSTGRES_DB: projectdb
POSTGRES_USER: projectdb
POSTGRES_PASSWORD: myawesomepassword
restart: always
networks:
- project
volumes:
# сохраняем файлы базы данных в именованный волум
- project_prod_db:/var/lib/postgresql/data
data:
image: registry.gitlab.com/USERNAME/REPONAME
volumes:
# такая запись волумом говорит о том, что указанные ниже папки из этого контейнера будут проброшены
# в каждый контейнер, который зависит от этого контейнера через директиву 'volumes_from'
- /etc/nginx
- /srv/www/app
- /usr/local/etc/php/conf.d
volumes:
project_prod_db:
driver: local
system-tmp:
driver: local
networks:
web:
# говорим о том, что сеть web - внешняя (зачем она нужна? Подробнее в разделе "docker-nginx")
external:
name: web
# простое определение сети говорит о том, что сеть - внутренняя. Значит она будет создана при старте проекта.
# Ее название: PROJECTNAME_NETWORKNAME. Например: project_project
project:
\ No newline at end of file
# версия файла. Подробнее https://docs.docker.com/compose/compose-file/
version: '2'
# описание сервисов проекта. При создании проекта названия контейнеров будут
# создаваться следующим образом: будет подставляться название проекта, затем
# подчеркивание, затем название контейнера.
# Название проекта берется из названия папки, в которой сейчас мы находимся.
services:
# таким образом, если проект называется examplesite, то контейнер web будет
# называться examplesite_web_1, где 1 - номер контейнера (в docker-compose)
# есть возможность запустить несколько контейнеров в целях масштабирования
web:
image: nginx:latest # образ
# прокидываем порт. Внимание: во время запуска проекта все остальные
# программы, занимающие 80 порт, должны быть, конечно же, выключены
ports:
- 80:80
volumes_from: # берем волумы, проброшенные с контейнера data
- data
# пробрасываем папку docker/nginx из текущей папки в системе в /etc/nginx
# папку в проекте
volumes: #
- ./docker/nginx/:/etc/nginx/:ro
# этот контейнер зависит от php и связывается с ним
depends_on:
- php
php:
image: atnartur/php:7.0.11-fpm-phalcon3.0.1
working_dir: /srv/www/app # рабочая директория, в которй будут запускаться все команды
# ждем полного запуска базы данных, выполняем миграции и запускаем php-fpm
command: sh -c "./wait-for-it.sh db:3306 && php vendor/bin/phinx migrate -e docker && php-fpm -RF"
ports:
- 9000:9000
depends_on:
- db
volumes_from:
- data
volumes:
# именованный волум - хранится в недрах докера в файловой системе
- system-tmp:/tmp
- ./docker/fpm-pool.conf:/usr/local/etc/php-fpm.d/www.conf
- ./docker/config_server.prod.json:/srv/www/app/app/config/server.json
db:
image: mdillon/postgis:9.6
ports:
- 5432:5432
# проброс переменных окружения
environment:
POSTGRES_DB: projectdb
POSTGRES_USER: projectdb
POSTGRES_PASSWORD: myawesomepassword
volumes:
- db:/var/lib/postgresql/data
# админка БД
pgweb:
image: donnex/pgweb
depends_on: # зависит от базы данных
- db
ports: # запускается на нестандартном порту чтобы не блокировать основной порт
- 8081:8080
# подключем контейнер data, который был собран на предыдущем шаге
data:
image: registry.gitlab.com/USERNAME/REPONAME
# в целях разработки жестко прокидываем текущую папку проекта в контейнер для того,
# чтобы в контенерах сразу же отображались изменения, которые мы производим.
volumes:
- ./:/srv/www/app
# определение волумов - подробнее https://docs.docker.com/engine/tutorials/dockervolumes/
volumes:
system-tmp:
driver: local
db:
driver: local
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
types {
text/html html htm shtml;
text/css css;
text/xml xml rss;
image/gif gif;
image/jpeg jpeg jpg;
application/x-javascript js;
application/atom+xml atom;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.ms-excel xls;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
#application/octet-stream eot;
application/octet-stream iso img;
application/octet-stream msi msp msm;
application/ogg ogx;
audio/midi mid midi kar;
audio/mpeg mpga mpega mp2 mp3 m4a;
audio/ogg oga ogg spx;
audio/x-realaudio ra;
audio/webm weba;
video/3gpp 3gpp 3gp;
video/mp4 mp4;
video/mpeg mpeg mpg mpe;
video/ogg ogv;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
application/x-font-ttf ttf;
application/font-otf otf;
application/octet-stream eot;
application/font-woff woff;
}
user root;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#set_real_ip_from 172.0.0.0/8;
real_ip_header X-Real-IP;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
# gzip on;
server {
listen 80;
charset UTF-8;
index index.php index.html index.htm;
set $root_path '/srv/www/app/public';
root $root_path;
access_log /dev/stdout;
error_log stderr error;
try_files $uri $uri/ @rewrite;
location @rewrite {
rewrite ^/(.*)/$ /$1 permanent;
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location ~ \.php {
fastcgi_pass php:9000;
fastcgi_index /index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REMOTE_ADDR $remote_addr;
}
location ~* ^/(css|img|js|flv|swf|download)/(.+)$ {
root $root_path;
}
location ~ /\.ht {
deny all;
}
}
}
#!/usr/bin/env bash
# Use this script to test if a given TCP host/port are available
cmdname=$(basename $0)
echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
usage()
{
cat << USAGE >&2
Usage:
$cmdname host:port [-s] [-t timeout] [-- command args]
-h HOST | --host=HOST Host or IP under test
-p PORT | --port=PORT TCP port under test
Alternatively, you specify the host and port as host:port
-s | --strict Only execute subcommand if the test succeeds
-q | --quiet Don't output any status messages
-t TIMEOUT | --timeout=TIMEOUT
Timeout in seconds, zero for no timeout
-- COMMAND ARGS Execute command with args after the test finishes
USAGE
exit 1
}
wait_for()