Использование docker для чайников
Содержание:
- Enabling/disabling Apache extensions
- Step 1 — Downloading Laravel and Installing Dependencies
- Setting parameters in php.ini
- 3 ответа
- TL; DR
- Шаг 3 — Постоянное сохранение данных
- Start a New MySQL Container
- Linux Installation
- Setting Up
- Usage
- Contributing
- apache
- MySQL Docker Containers
- php + apache + nginx
- Profiling with Blackfire
- Заключение
Enabling/disabling Apache extensions
You can enable/disable Apache extensions using the environment variable.
For instance:
version: '3' services: my_app: image: thecodingmachine/php:7.4-v3-apache-node8 environment: # Enable the DAV extension for Apache APACHE_EXTENSION_DAV: 1 # Enable the SSL extension for Apache APACHE_EXTENSION_SSL: 1
As an alternative, you can use the global variable:
Apache modules enabled by default: access_compat, alias, auth_basic, authn_core, authn_file, authz_core, authz_host, authz_user, autoindex, deflate, dir, env, expires, filter, mime, mpm_prefork, negotiation, php7, reqtimeout, rewrite, setenvif, status
Apache modules available: access_compat, actions, alias, allowmethods, asis, auth_basic, auth_digest, auth_form, authn_anon, authn_core, authn_dbd, authn_dbm, authn_file, authn_socache, authnz_fcgi, authnz_ldap, authz_core, authz_dbd, authz_dbm, authz_groupfile, authz_host, authz_owner, authz_user, autoindex, buffer, cache, cache_disk, cache_socache, cgi, cgid, charset_lite, data, dav, dav_fs, dav_lock, dbd, deflate, dialup, dir, dump_io, echo, env, ext_filter, file_cache, filter, headers, heartbeat, heartmonitor, ident, include, info, lbmethod_bybusyness, lbmethod_byrequests, lbmethod_bytraffic, lbmethod_heartbeat, ldap, log_debug, log_forensic, lua, macro, mime, mime_magic, mpm_event, mpm_prefork, mpm_worker, negotiation, php7, proxy, proxy_ajp, proxy_balancer, proxy_connect, proxy_express, proxy_fcgi, proxy_fdpass, proxy_ftp, proxy_html, proxy_http, proxy_scgi, proxy_wstunnel, ratelimit, reflector, remoteip, reqtimeout, request, rewrite, sed, session, session_cookie, session_crypto, session_dbd, setenvif, slotmem_plain, slotmem_shm, socache_dbm, socache_memcache, socache_shmcb, speling, ssl, status, substitute, suexec, unique_id, userdir, usertrack, vhost_alias, xml2enc
Step 1 — Downloading Laravel and Installing Dependencies
As a first step, we will get the latest version of Laravel and install the dependencies for the project, including Composer, the application-level package manager for PHP. We will install these dependencies with Docker to avoid having to install Composer globally.
First, check that you are in your home directory and clone the latest Laravel release to a directory called :
Move into the directory:
Next, use Docker’s image to mount the directories that you will need for your Laravel project and avoid the overhead of installing Composer globally:
Using the and flags with creates an ephemeral container that will be bind-mounted to your current directory before being removed. This will copy the contents of your directory to the container and also ensure that the folder Composer creates inside the container is copied to your current directory.
As a final step, set permissions on the project directory so that it is owned by your non-root user:
This will be important when you write the Dockerfile for your application image in Step 4, as it will allow you to work with your application code and run processes in your container as a non-root user.
With your application code in place, you can move on to defining your services with Docker Compose.
Setting parameters in php.ini
By default, the base file used is the development php.ini file that comes with PHP.
You can use the production file using the environment variable:
You can override parameters in using the PHP_INI_XXX environment variables:
version: '3' services: my_app: image: thecodingmachine/php:7.4-v3-apache-node8 environment: # set the parameter memory_limit=1g PHP_INI_MEMORY_LIMIT: 1g # set the parameter error_reporting=EALL PHP_INI_ERROR_REPORTING: E_ALL
Absolutely all parameters can be set.
Internally, the image will map all environment variables starting with .
If your parameter contains a dot («.»), you can replace it with a double underscore («__»).
For instance:
3 ответа
2
Лучший ответ
Я решил этот вопрос и создал репо для всех, кому интересно более подробное объяснение или доказательство концепции.
См. Мой репо: https://github.com/dambrogia/docker-testing
TL; DR
Подход, который я использовал для этого, заключался в проксировании всех запросов apache в любые файлы на PHP-FPM через . Порт 9000 по умолчанию
Вы можете увидеть это Apache настройки в действии .
Параметр определяет, где файлы отображаются в контейнере PHP.
04 нояб. 2017, в 06:23
Поделиться
3
Если вы работаете с PHP и хотите иметь один процесс для каждого контейнера, то я рекомендую использовать Nginx и использовать PHP-FPM, так как он значительно упрощает настройку, чем Apache для этого типа настройки (по крайней мере, то, что я мы нашли).
Вам необходимо обеспечить общий общий том как для контейнеров Nginx, так и для PHP. В этом томе у вас будет ваш . Вот грубый пример docker-compose.yml:
Затем вы выполните следующую команду в каталоге, где файл :
Причиной «префикса» является то, что вы создаете группировку проектов для своих контейнеров, чтобы не столкнуться с другими именами контейнеров.
Естественно, вам понадобится конфигурация сайта nginx, которая указывает на . У вас не будет никаких требований к конфигурации для контейнера php-fpm.
Замечание относительно конфигурации nginx. Вышеупомянутый файл docker-compose.yml является неполным без ссылки на php-контейнер в конфигурации nginx. Это будет выглядеть так (грубо говоря):
Вы заметите, что я назвал контейнер «php7», вы могли бы добавить еще один контейнер «php5» в этот а затем это позволит вам определить сайты nginx, которые используют разные версии PHP, все запущенные на одном и том же докере, составить настройку.
Я понимаю, что это не отвечает на ваш вопрос напрямую, так как он не решает проблему с помощью apache, но это альтернатива для рассмотрения.
Надеюсь, это по крайней мере дает вам идеи, помогающие решить вашу установку.
29 окт. 2017, в 19:48
Поделиться
-1
Вы столкнулись с мемом о том, что «контейнеры должны делать одно», что хорошо, но это не значит, что вы должны разбить его так далеко. Контейнер LAMP совершенно нормален в Docker-land, и я не знаю, какие усилия были предприняты для разделения Apache и PHP — я подозреваю, что это трата инженерных усилий.
Как вы говорите, вы хотите иметь возможность запускать разные версии PHP. Это абсолютно нормально, и вы должны настроить это в своем . Если вы намерены построить набор контейнеров, которые могут наследовать ваши сервисы, тогда вы можете просто создать базовый контейнер Apache, на котором вы добавите PHP в наследование .
Я запускаю набор микросервисов, которые используют комбинацию 5.6 и 7.0. Все они наследуются из очень простой (разной версии: 3.5, 3.6 и последней, что станет 3.7). Это займет около 15 минут, чтобы скопировать и вставить мои требования к сверху, плюс немного настройки контейнера, которые я, вероятно, сделаю в любом случае. Итак, если ваша цель — готовый к запуску набор контейнеров, я не уверен, сколько времени вы будете экономить на практике.
Все сказанное, если вы действительно хотите это сделать, вы можете изучить механизм, который использует Пивик. Я не знаком с этим, но контейнер PHP обслуживает FastCGI, и его необходимо проксировать через веб-сервер в другом контейнере.
29 окт. 2017, в 20:14
Поделиться
Шаг 3 — Постоянное сохранение данных
В Docker имеются мощные и удобные средства для постоянного сохранения данных. В нашем приложении мы будем использовать тома и монтируемые образы для постоянного сохранения файлов базы данных, приложения и конфигурации. Тома обеспечивают гибкость резервного копирования и сохранение по прекращении жизненного цикла контейнера, а привязываемые монтируемые образы упрощают изменение кода во время разработки с немедленным отражением изменений файлов или каталогов хоста в контейнерах. Мы используем оба варианта.
Предупреждение! Использование привязываемых монтируемых образов позволяет изменять файловую систему хоста через работающие в контейнеры процессы, что включает создание, изменение или удаление важных системных файлов или каталогов. Это мощная возможность с функциями безопасности, которая может повлиять на процессы без Docker в системе хоста
Привязывемые монтируемые образы следует использовать с осторожностью
Определите в файле том с именем в определении службы для постоянного сохранения базы данных MySQL:
~/laravel-app/docker-compose.yml
Том с именем используется для постоянного сохранения содержимого папки внутри контейнера. Это позволяет останавливать и перезапускать службу без потери данных.
Добавьте в конце файла определение тома :
~/laravel-app/docker-compose.yml
С этим определением вы сможете использовать этот том для разных служб.
Затем добавьте привязку монтируемого образа к службе для файлов конфигурации MySQL, которые вы создадите на шаге 7:
~/laravel-app/docker-compose.yml
Этот монтируемый образ привязывает файл к каталогу в контейнере.
Затем добавьте монтируемые образы в службу . Их будет два: один для кода приложения, а другой — для определения конфигурации Nginx, которое вы создадите на шаге 6:
~/laravel-app/docker-compose.yml
Первый монтируемый образ привязывает код приложения в каталоге к каталогу внутри контейнера. Файл конфигурации, добавляемые в , также монтируется в в контейнере, что позвоялет добавлять и изменять содержимое каталога конфигурации по мере необходимости.
В заключение добавьте следующие привязки монтируемых образов в службу для кода приложения и файлов конфигурации:
~/laravel-app/docker-compose.yml
Служба привязывает монтируемый образ папки , который содержит код приложения, к папке . Это ускорит процесс разработки, поскольку любые изменения в локальном каталоге приложения будут немедленно отражаться в контейнере. Также вы привязываете файл конфигурации PHP к файлу в контейнере. На шаге 5 вы создадите локальный файл конфигурации PHP.
Теперь ваш файл будет выглядеть следующим образом:
~/laravel-app/docker-compose.yml
Когда закончите вносить изменения, сохраните файл и закройте редактор.
Записав файл , вы сможете создать персонализированный образ вашего приложения.
Start a New MySQL Container
Docker MySQL Containers are very straight forward. Starting a new server instance is very simple.
Following Example will start a new MySQL instance called «mysql_server» from the «MySQL 5.7» image.
Note that most important option is the MYSQL_ROOT_PASSWORD, We also use the -d option to run the container as a background process.
You can get an interactive shell session to the MySQL instance with the docker exec command.
To get direct interactive session to mysql console from the host, type:
Docker MySQL Environment Variables
When we start a new instance, we can adjust the configuration of the MySQL instance by passing one or more environment variables with docker run command.
Following Table shows environment variables used with Docker MySQL.
- MYSQL_ROOT_PASSWORD — Set Password for the MySQL root user. This variable is mandatory.
- MYSQL_USER, MYSQL_PASSWORD — Create new MySQL user and Set user password. This is optional.
- MYSQL_DATABASE — Create a New Database on startup. This is optional. If a user is created, the user will be granted superuser access to the database.
- MYSQL_ALLOW_EMPTY_PASSWORD — If set to «yes», New container can start with empty root password.
- MYSQL_RANDOM_ROOT_PASSWORD — If set to «yes», a random initial password for the root user will be created.
In the Following example, we create a new container with a new MySQL database called «test_db».
Start a container with a new MySQL user:
Start a mysql container with an empty root password:
Link with another docker container
Often you will need to link your mysql instance with other containers. For example, following command will start a new Apache HTTPD container with a link to a mysql instance called «mysql_server».
The apache container now has access to the mysql server inside mysql container. When connecting to the mysql server, mysql host should be the Name or ID of the MySQL container.
Start a MySQL container with Remote Access
In Order to allow remote access to the MySQL container, we need to map host port 3306 with container port 3306, when we create a new instance.
From the host machine you can access the MySQL Console with 127.0.0.1 as the MySQL host.
Note that port mapping should be done when a container is created.
Using a custom MySQL configuration file
The startup configuration file is /etc/mysql/my.cnf file, and that file in turn includes any files found in the /etc/mysql/conf.d or /etc/mysql/mysql.conf.d directory that end with .cnf extension.
When we start a new container, we can replace the configuration directory with a directory on the host machine. For example, Create a directory called /var/config on the host machine.
Then create the mysqld.cnf file inside the /var/config directory and add any mysql configurations to the mysqld.cnf file.
Now we can mount /var/config directory as /etc/mysql/mysql.conf.d inside the mysql container.
As per the above example, we use -v flag to replace /etc/mysql/mysql.conf.d directory with local /var/config directory.
Using a custom Data Directory
Same way we can also mount the MySQL data directory from the host machine. Default data directory on docker mysql is «/var/lib/mysql».
First, create the data directory on the host computer:
Then start the server instance with the local data directory:
Backup Databases from the Host
With docker exec command we can create database dumps from the host machine.
Following command will dump ‘example_db’ database from the «mysql_server» instance.
The following command will dump all databases from the mysql container.
Linux Installation
First, let’s download the Docker repository. Run the following:
sudo apt-get update
Followed by:
sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
Next run:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
To verify you have the repository run the following:
sudo apt-key fingerprint 0EBFCD88
And you should get something like this:
pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88uid Docker Release (CE deb) <docker@docker.com>sub 4096R/F273FCD8 2017-02-22
Now to install Docker you just need to do the following:
sudo apt-get update && sudo apt-get install docker-ce
Now to get Docker Compose run:
sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && sudo chmod +x /usr/local/bin/docker-compose
To test if your installation was setup correctly, run:
docker-compose --version
And you should get something similar to:
docker-compose version 1.22.0, build 1719ceb
Setting Up
After installing Docker run it and create file called. This file is essentially and instructions sheet for Docker.
In it paste the following:
version: '3.3'services: db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: 'db'# So you don't have to use root, but you can if you likeMYSQL_USER: 'user'# You can use whatever password you likeMYSQL_PASSWORD: 'password'# Password for root accessMYSQL_ROOT_PASSWORD: 'password' ports:# <Port exposed> : < MySQL Port running inside container> - '3306:3306' expose: # Opens port 3306 on the container - '3306' # Where our data will be persisted volumes: - my-db:/var/lib/mysql# Names our volumevolumes: my-db:
Great, now we can start our container. In your command line or terminal, into the directory where you made your and from there, run (this might take a while on the first run because Docker needs to pull the containers). We should now have a MySQL instance running on .
Your output should look similar to this:
And that’s it! If you want to change databases from MySQL to something else, all you have to do is change the and restart Docker Compose.
Here’s a simple Postgres DB example:
version: '3.3'services:db: image: postgres restart: always environment: POSTGRES_PASSWORD: password
As you can see, using Docker Compose provides us with a ton a flexibility and configurations. We can switch databases in about 30 seconds if we wanted to!
Now let’s play with our new database!
Usage
To use this image directly, you can use a docker-compose file to keep things nice and simple… if you have a load balancer like traefik and mysql containers running on another docker network, you may have something like this…
version: "2" services: myservice: build: labels: - "traefik.backend=myservice" - "traefik.frontend.rule=Host:myservice.docker.localhost" environment: - MYSQL_HOST=mysql - APACHE_SERVER_NAME=myservice.docker.localhost - PHP_SHORT_OPEN_TAG=On - PHP_ERROR_REPORTING=E_ALL - PHP_DISPLAY_ERRORS=On - PHP_HTML_ERRORS=On - PHP_XDEBUG_ENABLED=true networks: - default volumes: - ./:/app # ADD in permission for setting system time to host system time cap_add: - SYS_TIME - SYS_NICE networks: default: external: name: docker_docker-localhost
Then run…
docker-compose up -d
This will patch the container through to traefik load balancer running from another dc file.
If you would like to add to this, expand on this, maybe you don’t want to map your volume and want to copy files for a production system. You can create your own Dockerfile based on this image…
Contributing
There is one branch per minor PHP version and version of the image.
Please submit your pull requests to the lowest branch where is applies.
The Dockerfiles and the README are generated from a template using Orbit.
If you want to modify a Dockerfile or the README, you should instead edit the
or and then run the command:
$ orbit run generate
This command will generate all the files from the «blueprint» templates.
You can then test your changes using the command:
PHP_VERSION=7.4 BRANCH=v3 VARIANT=apache ./build-and-test.sh
Adding additional images
To add a new version (php, node, apache, …), please edit the following files :
- utils/README.blueprint.md
- orbit.yml: Your image in generation task
- .travis.yml: To check the new image
- build-and-test.sh: Add your image in test
apache
Начнем, пожалуй, с самого популярного сервера — Apache.
Создадим директорию проекта:
- project
- src
- docker-compose.yml
Конфиг будет выглядеть таким образом:
Что здесь происходит:
- — указываем какой образ нам нужно и его версию (список доступных версий и модификаций можно посмотреть в соответствующем docker-hub).
- — пробрасываем порты между docker и нашей машиной, т.е. все запросы которые будут идти на 80 порт нашей машины, будут транслироваться на 80 порт docker.
- — линкуем директорию на нашей машине, с рабочей директорий apache, т.е. все файлы находящиеся в директории src, будут доступны для apache, как будто они лежат в директории htdocs (обратное тоже работает, все что создано в docker «копируется» на локальную машину).
Создадим файл src/index.html в рабочей директории с содержимым:
Запускаем наш проект:
Переходим в браузер по адресу ПК и наблюдаем приветствие нашего сервера.
Чтобы уничтожить контейнеры нашего проекта, достаточно в консоле выполнить Ctrl+C.
Работа в фоновом режиме
Если вам необходимо запустить docker и далее работать в консоле, то можно запустить проект в фоном режиме:
После запуска, консоль будет доступна для работы.
Чтобы в данной ситуации уничтожить контейнер, необходимо его остановить и удалить, но для начала, нужно узнать его ID:
В моем случае получился такой вывод:
Теперь останавливаем и удаляем наш контейнер:
Либо можно поступить грубо и сразу удалить:
MySQL Docker Containers
Think about a container as a “lightweight virtual machine”. Unlike virtual machines though, containers do not require an entire operating system, all required ibraries and the actual application binaries. The same Linux kernel and libraries can be shared between multiple containers running on the host. Docker makes it easy to package Linux software in self-contained images, where all software dependencies are bundled and deployed in a repeatable manner. An image will have exactly the same software installed, whether we run it on a laptop or on a server. The key benefit of Docker is that it allows users to package an application with all of its dependencies into a standardized unit (container). Running many containers allows each one to focus on a specific task; multiple containers then work in concert to implement a distributed system.
The traditional way to run a MySQL database is to install the MySQL packages on a host (bare-metal, virtual machine, cloud instance), and applications would just have to connect to the listening port. Most of the management tasks, for example, configuration tuning, backup, restore, database upgrade, performance tweaking, troubleshooting and so on have to be executed on the database host itself. You would expect to have several ports accessible for connection, for example port TCP 22 for SSH, TCP 3306 for MySQL or UDP 514 for syslog.
In a container, think of MySQL as one single unit that only serve MySQL related stuff on port 3306. Most of the operation should be performed under this single channel. Docker works great in packaging your application/software into one single unit, which you can then deploy anywhere as long as Docker engine is installed. It expects the package, or image to be run as a single process per container. With Docker, the flow would be you (or someone) build a MySQL image using a specific version and vendor, package the image and distribute to anybody who wants to quickly fire a MySQL instance.
php + apache + nginx
https://hub.docker.com/_/nginx/https://hub.docker.com/_/php/https://hub.docker.com/_/httpd/
Наверное, самая популярная связка для веб-проектов. Схематично это выглядит так:
Пара замечаний:
- php используется как php-fpm, потому что быстрее и моднее;
- apache используется, потому что популярен и htaccess.
Для того чтобы все настроить нам нужно будет также слинковать конфиг apache, и таким образом docker-compose будет выглядеть так:
Так как на просторах интернета я не нашел нормальный конфиг (оке, я просто не искал), а под рукой как раз docker, то решено было вытаскивать его из стандартного контейнера.
Уложилось все в 3 команды:
После выполнения данных команд, в текущей директории появится файл httpd.conf, который мы и будем использовать в качестве основы.
По сути, это простое копирование из запущенного контейнера.
Создаем файл /httpd/httpd.conf в рабочей директории, который после правок выглядит так:
Создаем файл /nginx/nginx.conf в рабочей директории со следующим содержимым:
В строке мы опять указываем не IP адрес, а название контейнера (вспоминаем про магию с hosts).
Для тестинга, нам нужно будет проверить, работает ли PHP и работает ли Apache.
Сформируем такую структуру проекта:
- nginx
- httpd
- src
- protected
- .htaccess
- index.html
- index.php
- protected
- docker-compose.yml
Содержимое .htaccess:
Содержимое index.php:
Содержимое index.html:
Если все настроено корректно, то картина должна быть следующей:
- /index.php — откроется информация о php
- /protected/index.html — откроется 403 ошибка apache
- /protected/.htaccess — откроется 403 ошибка nginx (визуально они отличаются)
Profiling with Blackfire
This image comes with the Blackfire PHP probe. You can install it using:
PHP_EXTENSION_BLACKFIRE=1
By default, the image expects that the blackfire agent is started in another container.
Your file will typically look like this:
docker-compose.yml
version: '3.3' services: php: image: thecodingmachine/php:7.4-v3-apache ports: - "80:80" environment: PHP_EXTENSION_BLACKFIRE: 1 blackfire: image: blackfire/blackfire environment: # Exposes the host BLACKFIRE_SERVER_ID and TOKEN environment variables. - BLACKFIRE_SERVER_ID - BLACKFIRE_SERVER_TOKEN # You can also use global environment credentials : # BLACKFIRE_SERVER_ID: SERVER-ID # BLACKFIRE_SERVER_TOKEN: SERVER-TOKEN
The image assumes that the Blackfire agent is accessible via the URL (like in the exemple above).
If for some reason, the container name is not «blackfire», you can customize the agent URL with the environment variable:
docker-compose.yml
version: '3.3' services: php: image: thecodingmachine/php:7.4-v3-apache environment: PHP_EXTENSION_BLACKFIRE: 1 BLACKFIRE_AGENT: myblackfire # ... myblackfire: image: blackfire/blackfire environment: # ...
Заключение
Теперь на вашем сервере работает приложение набора LEMP, которое вы протестировали, получив доступ к начальной странице Laravel и создав миграцию базы данных MySQL.
Главный фактор для простоты установки — Docker Compose, позволяющий создавать группу контейнеров Docker, определенную в одном файле, с помощью одной команды. Если вы хотите узнать больше о постоянной интеграции с Docker Compose, ознакомьтесь с обучающим модулем «Настройка среды постоянного тестирования интеграции с Docker и Docker Compose в Ubuntu 16.04». Если вы хотите ускорить процесс развертывания вашего приложения Laravel, вам поможет ресурс «Автоматическое развертывание приложений Laravel с помощью Deployer в Ubuntu 16.04».