IT-инфраструктура для бизнеса и творчества

Среда разработки PHP на базе Docker

Решение, которое позволит создать на локальном компьютере универсальную среду разработки на PHP за 30 — 40 минут.

Оглавление

Почему Docker?

  • Docker не является VM-системой, он не моделирует аппаратное обеспечение компьютера. Используя Docker вы получите минимальное потребление ресурсов. Docker-контейнеры взаимодействуют напрямую с ядром вашего компьютера (или ядром хоста), но при этом изолируют программу на уровне процесса.
  • Высокая скорость развертывания. Вы можете использовать готовые docker-образы, которые устанавливаются и запускаются за секунды.
  • Приложения, находящееся внутри docker-контейнеров, можно запустить на любом компьютере с установленным Docker, при этом окружение будет одинаковым.
  • Возможность простой сегрегации пользовательских данных и контейнеров-сервисов. Если вы сломаете или удалите docker-контейнер, то данные не потеряются, так как они не будут принадлежать контейнеру. Контейнер выполняет лишь функцию сервиса, и не хранит данные, которые нельзя потерять между запусками.
  • Вы можете очень быстро добавлять новые контейнеры, изменять их конфигурацию, запускать различные версии баз данных на одной машине.

Требования

  • Git.
  • Docker engine 19.x и выше.

Возможности и особенности среды разработки

  • Несколько версий PHP — 7.3 и 7.1 с набором наиболее востребованных расширений.
  • Возможность использовать для web-проектов разные версии PHP.
  • Готовый к работе монитор процессов Supervisor.
  • Предварительно сконфигурированный веб-сервер Nginx.
  • Базы данных: MySQL 5.7, MySQL 8, PostgreSQL (latest), MongoDB 4.2, Redis (latest).
  • Настройка основных параметров окружения через файл .env.
  • Возможность модификации сервисов через docker-compose.yml.
  • Последняя версия docker-compose.yml.
  • Все docker-контейнеры базируются на официальных образах.
  • Структурированный Dockerfile для создания образов PHP.
  • Каталоги большинства docker-контейнеров, в которых хранятся пользовательские данные и параметры конфигурации смонтированы на локальную машину.

В целом, среда разработки удовлетворяет требованию — при использовании Docker каждый контейнер должен содержать в себе только один сервис.

Репозиторий проекта

Структура проекта

Рассмотрим структуру проекта.

├── .env-example ├── .gitignore ├── .ssh ├── README.md ├── docker-compose.yml ├── mongo ├── mysql-5.7 ├── mysql-8 ├── nginx ├── php-ini ├── php-workers ├── php-workspace ├── postgres ├── projects └── redis

Примечание

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

.gitkeep — является заполнением каталога, это фиктивный файл, на который не следует обращать внимание.

.env-example

Пример файла с основными настройками среды разработки.

# Временная зона WORKSPACE_TIMEZONE='Europe/Moscow' # XDEBUG DOCKER_PHP_ENABLE_XDEBUG='on' # Настройки Nginx # Порт, который следует использовать # для соединения с локального компьютера NGINX_PORT=80 # Настройки Redis # Порт, который следует использовать # для соединения с локального компьютера REDIS_PORT=6379 # Настройки Postgres POSTGRES_DB=test POSTGRES_USER=pg_user POSTGRES_PASSWORD=secret POSTGRES_PORT=54322 # Настройки общие для MySQL 8.x и MySQL 5.7.x MYSQL_ROOT_PASSWORD=secret MYSQL_DATABASE=test # Настройки MySQL 8.x # Порт, который следует использовать # для соединения с локального компьютера MYSQL_8_PORT=4308 # Настройки MySQL 5.7.x # Порт, который следует использовать # для соединения с локального компьютера MYSQL_5_7_PORT=4307 # Настройки MongoDB # Порт, который следует использовать # для соединения с локального компьютера MONGO_PORT=27017 # Настройки PHP 7.3 # Внешний порт, доступен с локального компьютера PHP_7_3_PORT=9003 # Настройки PHP 7.1 # Внешний порт, доступен с локального компьютера PHP_7_1_PORT=9001

.gitignore

Каталоги и файлы, в которых хранятся пользовательские данные, код ваших проектов и ssh-ключи внесены в. gitignore.

.ssh

Этот каталог предназначен для хранения ssh-ключей.

readme.md

Документация.

docker-compose.yml

Документ в формате YML, в котором определены правила создания и запуска многоконтейнерных приложений Docker. В этом файле описана структура среды разработки и некоторые параметры необходимые для корректной работы web-приложений.

mongo

Каталог базы данных MongoDB.

├── configdb │ └── mongo.conf ├── db └── dump

mongo.conf — Файл конфигурации MongoDB. В этот файл можно добавлять параметры, которые при перезапуске MongoDB будут применены.

db — эта папка предназначена для хранения пользовательских данных MongoDB.

dump — каталог для хранения дампов.

mysql-5.7

Каталог базы данных MySQL 5.7.

├── conf.d │ └── config-file.cnf ├── data ├── dump └── logs

config-file.cnf — файл конфигурации. В этот файл можно добавлять параметры, которые при перезапуске MySQL 5.7 будут применены.

data — эта папка предназначена для хранения пользовательских данных MySQL 5.7.

dump — каталог для хранения дампов.

logs — каталог для хранения логов.

mysql-8

Каталог базы данных MySQL 8.

├── conf.d │ └── config-file.cnf ├── data ├── dump └── logs

config-file.cnf — файл конфигурации. В этот файл можно добавлять параметры, которые при перезапуске MySQL 8 будут применены.

data — эта папка предназначена для хранения пользовательских данных MySQL 8.

dump — каталог для хранения дампов.

logs — каталог для хранения логов.

nginx

Эта папка предназначена для хранения файлов конфигурации Nginx и логов.

├── conf.d │ ├── default.conf │ └── vhost.conf └── logs

default.conf — файл конфигурации, который будет применён ко всем виртуальным хостам.

vhost.conf — здесь хранятся настройки виртуальных хостов web-проектов.

Рассмотрим vhost.conf подробнее:

server { listen 80; index index.php index.html; server_name project-1.localhost; error_log /var/log/nginx/project-1.error.log; access_log /var/log/nginx/project-1.access.log combined if=$loggable; root /var/www/project-1.ru; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php-7.3:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; } } server { listen 80; index index.php index.html; server_name project-2.localhost; error_log /var/log/nginx/project-2.error.log; access_log /var/log/nginx/project-2.access.log combined if=$loggable; root /var/www/project-2.ru; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php-7.1:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_script_name; } }

В файле конфигурации описаны настройки для двух web-проектов — project-1.localhost и project-2.localhost.

Здесь следует обратить внимание на то, как производится перенаправление запросов к нужному docker-контейнеру.

Например, для проекта project-1.localhost указано:

fastcgi_pass php-7.3:9000;

php-7.3 — название docker-контейнера, а 9000 — порт внутренней сети. Контейнеры между собой связаны через внутреннюю сеть, которая определена в файле docker-compose.yml.

php-ini

В этом каталоге находятся файлы конфигурации PHP.

├── 7.1 │ └── php.ini └── 7.3 └── php.ini

Для каждой версии PHP — свой файл конфигурации.

php-workers

Место для хранения файлов конфигурации Supervisor.

├── 7.1 │ └── supervisor.d │ └── 7.3 └── supervisor.d

Для каждой версии PHP — могут быть добавлены свои файлы с настройками.

php-workspace

Здесь хранится файл, в котором описаны действия, выполняемые при создании образов docker-контейнеров PHP.

└── Dockerfile

Dockerfile — это текстовый документ, содержащий все команды, которые следует выполнить для сборки образов PHP.

postgres

Каталог для системы управления базами данных PostgreSQL.

├── .gitkeep ├── data └── dump

data — эта папка предназначена для хранения пользовательских данных PostgreSQL.

dump — каталог для хранения дампов.

projects

Каталог предназначен для хранения web-проектов.

Вы можете создать в это каталоге папки, и поместить в них ваши web-проекты.

Например:

project-1.ru project-2.ru ...

Содержимое каталога projects доступно из контейнеров php-7.1 и php-7.3.

Если зайти в контейнер php-7.1 или php-7.3, то в каталоге /var/www будут доступны проекты, которые расположены в projects на локальной машине.

redis

Каталог key-value хранилища Redis.

├── conf └── data

conf — папка для хранения специфических параметров конфигурации.

data — если настройки конфигурации предполагают сохранения данных на диске, то Redis будет использовать именно этот каталог.

Программы в docker-контейнерах PHP

Полный перечень приложений, которые установлены в контейнерах php-7.x можно посмотреть в php-workspace/Dockerfile.

Здесь перечислим лишь некоторые, наиболее важные:

  • bash
  • htop
  • curl
  • Git
  • Сomposer
  • make
  • wget
  • NodeJS
  • Supervisor
  • npm

Начало работы

1. Выполните клонирование данного репозитория в любое место на вашем компьютере.

git clone https://github.com/drandin/docker-php-workspa

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

2. Скопируйте файл .env-example в .env

cp .env-example .env

Если это необходимо, то внесите изменения в файл .env. Измените настройки среды разработки в соответствии с вашими требованиями.

3. Выполните клонирование web-проектов в каталог projects.

Для примера, далее мы будем исходить из предположения, что у вас есть 2 проекта:

project-1.ru project-2.ru

project-1.ru — будет работать на версии PHP 7.3, а project-2.ru — на PHP 7.1.

4. Отредактируйте настройки виртуальных хостов Nginx.

Файл конфигурации виртуальных хостов находится в каталоге ./nginx/conf.d/.

5. Настройте хосты (доменные имена) web-проектов на локальной машине.

Необходимо добавить названия хостов web-проектов в файл hosts на вашем компьютере.

В файле hosts следует описать связь доменных имён ваших web-проектов в среде разработки на локальном компьютере и IP docker-контейнера Nginx.

На Mac и Linux этот файл расположен в /etc/hosts. На Windows он находится в C:\Windows\System32\drivers\etc\hosts.

Строки, которые вы добавляете в этот файл, будут выглядеть так:

127.0.0.1 project-1.localhost 127.0.0.1 project-2.localhost

В данном случае, мы исходим из того, что Nginx, запущенный в docker-контейнере, доступен по адресу 127.0.0.1 и web-сервер слушает порт 80.

Не рекомендуем использовать имя хоста с .dev на конце в среде разработки. Лучшей практикой является применение других названий — .localhost или .test.

6. [опционально, если это необходимо] Настройте маршрутизацию внутри контейнеров web-проектов.

Web-проекты должны иметь возможность отправлять http-запросы друг другу и использовать для этого название хостов.

Из одного запущенного docker-контейнера php-7.1 web-приложение № X должно иметь возможность отправить запрос к другому web-приложению № Y, которое работает внутри docker-контейнера php-7.3. При этом адресом запроса может быть название хоста, которое указано в файле /etc/hosts локального компьютера.

Чтобы это стало возможным нужно внутри контейнеров так же внести соответствующие записи в файл /etc/hosts.

Самый простой способ решить данную задачу — добавить секцию extra_hosts в описание сервисов php-7.1 и php-7.3 в docker-compose.yml.

Пример:

... php-7.1: ... extra_hosts: - 'project-1.localhost:IP_HOST_MACHINE' - 'project-2.localhost:IP_HOST_MACHINE' ...

IP_HOST_machine — IP адрес, по которому из docker-контейнера доступен ваш локальный компьютер.

Если вы разворачиваете среду разработки на Mac, то внутри docker-контейнера вам доступен хост docker.for.mac.localhost.

Узнать IP адрес вашего Mac можно при помощи команды, который нужно выполнить на локальной машине:

docker run -it alpine ping docker.for.mac.localhost

В результате вы получите, что-то подобное:

PING docker.for.mac.localhost (192.168.65.2): 56 data bytes 64 bytes from 192.168.65.2: seq=0 ttl=37 time=0.286 ms 64 bytes from 192.168.65.2: seq=1 ttl=37 time=0.504 ms 64 bytes from 192.168.65.2: seq=2 ttl=37 time=0.801 ms

После того, как вам станет известен IP-адрес, укажите его в секции extra_hosts в описание сервисов php-7.1 и php-7.3 в docker-compose.yml.

... php-7.1: ... extra_hosts: - 'project-1.localhost:192.168.65.2' - 'project-2.localhost:192.168.65.2' .

8. Настройте параметры соединения с системами хранения данных.

Хосты и порты сервисов

Для того, чтобы настроить соединения с базами данных из docker-контейнеров php-7.1 и php-7.3 следует использовать следующие названия хостов и порты:

Именно эти параметры следует использовать для конфигурации web-проектов.

Для соединения с базами данных с локальной машины:

  • Хост для всех баз данных — 127.0.0.1.
  • Порты — значения указанные в .env.

7. Создайте контейнеры и запустите их.

Выполните команду:

docker-compose build && docker-compose up -d

Создание контейнеров займёт некоторое время. Обычно от 10 до 30 минут. Дождитесь окончания процесса. Ваш компьютер не должен потерять доступ в интернет.

Если вы всё сделали правильно, то контейнеры будут созданы и запущены.

Откройте Docker Dashboard и убедитесь в этом:

Docker Dashboard на Mac.

8. Создайте SSH-ключи.

Для работы web-проектов могут потребоваться SSH-ключи, например для того, чтобы из контейнера при помощи Composer можно было установить пакет из приватного репозитория.

Создать SSH-ключи можно при помощи следующей команды:

ssh-keygen -f ./.ssh/id_rsa -t rsa -b 2048 -C "your-name@example.com"

Вместо your-name@example.com укажите свой Email.

В папку .ssh/ будут сохранены 2 файла — публичный и приватный ключ.

9. Проверьте созданные docker-контейнеры.

Выполните команду:

docker ps

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

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8d348959c475 docker-php-workspace_php-7.1 "docker-php-entrypoi…" 6 minuts ago Up 54 seconds 0.0.0.0:9001->9000/tcp php-7.1 a93399727ff6 docker-php-workspace_php-7.3 "docker-php-entrypoi…" 6 minuts ago Up 53 seconds 0.0.0.0:9003->9000/tcp php-7.3 5cd80ac95388 nginx:stable-alpine "/docker-entrypoint.…" 6 minuts ago Up 51 seconds 0.0.0.0:80->80/tcp nginx 70182bc9e44c mysql:5.7 "docker-entrypoint.s…" 6 minuts ago Up 54 seconds 33060/tcp, 0.0.0.0:4307->3306/tcp mysql-5.7 46f2766ec0b9 mysql:8.0.21 "docker-entrypoint.s…" 6 minuts ago Up 53 seconds 33060/tcp, 0.0.0.0:4308->3306/tcp mysql-8 a59e7f4b3c61 mongo:4.2 "docker-entrypoint.s…" 6 minuts ago Up 54 seconds 0.0.0.0:27017->27017/tcp mongo eae8d62ac66e postgres:alpine "docker-entrypoint.s…" 6 minuts ago Up 53 seconds 0.0.0.0:54322->5432/tcp postgres bba24e86778a redis:latest "docker-entrypoint.s…" 6 minuts ago Up 54 seconds 0.0.0.0:6379->6379/tcp redis

10. Установка зависимостей для web-приложений.

Если для работы web-приложений необходимо установить зависимости, например через менеджер пакетов Composer или NPM, то сейчас самое время сделать это.

В контейнерах php-7.1 и php-7.3 уже установлен и Composer и NPM.

Войдите в контейнер php-7.1:

docker exec -it php-7.1 bash

или

docker exec -it php-7.3 bash

Перейдите в рабочий каталог необходимого web-проекта и выполните требуемые действия.

Например, установите зависимости через Composer при помощи команды:

composer install

Вопросы и ответы

Несколько важных вопросов и ответов.

Как зайти в работающий docker-контейнер?

Выполните команду:

docker exec -it container_name bash

container_name — имя контейнера.

Как останавливать и удалить контейнеры и другие ресурсы среды разработки, которые были созданы?

docker-compose down

Как получить список всех контейнеров?

docker ps -a

Как получить подробную информацию о docker-контейнере?

docker inspect container_name

container_name — имя контейнера.

Как получить полный список расширений PHP, которые установлены в контейнере php-7.3?

Если контейнер php-7.3 запущен, то выполните команду:

docker exec -it php-7.3 php -m

Как удалить все контейнеры?

Удаление всех контейнеров:

docker rm -v $(docker ps -aq) # Все без исключения контейнеры будут удалены

Удаление всех активных контейнеров:

docker rm -v $(docker ps -q) # Все активные контейнеры будут удалены

Удаление всех неактивных контейнеров:

docker rm -v $(docker ps -aq -f status=exited) # Все неактивные контейнеры будут удалены

Развёртывание дампов MySQL, PostgreSQL и MongoDB

Если для работы web-проектов требуются перенести данные в хранилища, то следуйте описанным ниже инструкциям.

Как развернуть дамп PostgreSQL?

Выполните следующую команду на локальной машине:

docker exec -i postgres psql --username user_name database_name < /path/to/dump/pgsql-backup.sql

или зайдите в контейнер postgres и выполните:

psql --username user_name database_name < /path/to/dump/pgsql-backup.sql

user_name — имя пользователя. Значение postgres_USER (см. файл .env).

database_name — название базы данных. Значение postgres_DB (см. файл .env).

Как развернуть дамп MySQL?

Существует два варианта.

Вариант 1

Если требуется создать дополнительных пользователей, то следует это сделать перед началом процедуры загрузки дампа.

В файле mysql/conf.d/config-file.cnf отключите лог медленных запросов slow_query_log=0 или установите большое значение long_query_time, например 1000.

Если дамп сжат утилитой gzip, сначала следует распаковать архив:

gunzip databases-dump.sql.gz

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

docker exec -i mysql mysql --user=root --password=secret --force < databases-dump.sql

Указывать пароль в командной строке — плохая практика, не делайте так в производственной среде.

MySQL выдаст справедливое предупреждение:

mysql: [Warning] Using a password on the command line interface can be insecure

Ключ --force говорит MySQL, что ошибки следует проигнорировать и продолжить развёртывание дампа. Этот ключ иногда может пригодится, но лучше его без необходимости не применять.

Вариант 2

Воспользоваться утилитой Percona XtraBackup.

Percona XtraBackup — это утилита для горячего резервного копирования баз данных MySQL.

О том, как работать с XtraBackup можно узнать по ссылке: https://vc.ru/dev/158815-sozdanie-rezervnoy-kopii-mysql-pri-pomoshchi-utility-xtrabackup.

Как развернуть дамп MongoDB?

  • Скопируйте фалы дампа в каталог mongo/dump.
  • Войдите в контейнер mongo:
docker exec -it mongo sh

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

mongorestore -d database_name /dump/databases/database_nam

Git-репозиторий проекта

{ "author_name": "Игорь Драндин", "author_type": "self", "tags": ["selectel_\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f","postgresql","php","mysql","docker","dev"], "comments": 4, "likes": 8, "favorites": 33, "is_advertisement": false, "subsite_label": "dev", "id": 158897, "is_wide": true, "is_ugc": true, "date": "Wed, 16 Sep 2020 17:07:22 +0300", "is_special": false }
(function () { let cdnUrl = `https://specialsf378ef5-a.akamaihd.net/SelectelBranding/images/` let previousArticleNumber = null let currentArticleNumber = 0 let platform = 'Desktop' let articles = [ // { // name: 'camera', // url: `${cdnUrl}CameraCat`, // text: 'умную камеру для\u00A0наблюдения за\u00A0котиками', // link: '1', // num: 3 // }, { name: 'chill', url: `${cdnUrl}ChillCat`, text: 'трекер, который подскажет, когда пора отдохнуть', link: 'https://vc.ru/promo/288561-eye-tracker', num: 1 }, { name: 'cloud', url: `${cdnUrl}CloudCat`, text: 'котика: даёшь ему «пять», а\u00A0он делает бэкап в облако', link: 'https://vc.ru/dev/294799-maneki-neko', num: 2 } ] let buttonCycle = document.querySelector('.button--cycle') let buttonChoose = document.querySelector('.button--choose') let buttonMobile = document.querySelector('.button--mobile') let textField = document.querySelector('.selectel-footer-subtitle') let imageAgent = document.querySelector('.image--agent') let banner = document.querySelector('.selectel-footer') buttonCycle.addEventListener('click', cycleClick) buttonChoose.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) buttonMobile.addEventListener('click', () => sendEvent(`Promo ${articles[currentArticleNumber].num} Left`, 'Click')) let media = window.matchMedia("(max-width: 570px)") media.addEventListener('change', matchMedia) function matchMedia() { if (media.matches) { platform = 'Mobile' } else { platform = 'Desktop' } update() } matchMedia() function cycleClick(event) { sendEvent(`Promo ${articles[currentArticleNumber].num} Right`, 'Click') if (event) { event.preventDefault() event.stopPropagation() } window.open('https://vc.ru/tag/selectelDIY', '_blank') //cycle(event) } function cycle(event) { // incrementArticleNumber() textField.innerHTML = generatedText() imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?3' imageAgent.setAttribute("class", "") imageAgent.classList.add('image--agent', articles[currentArticleNumber].name) banner.href = articles[currentArticleNumber].link } function update() { banner.href = articles[currentArticleNumber].link imageAgent.src = articles[currentArticleNumber].url + platform + '.svg' textField.innerHTML = generatedText() } function incrementArticleNumber() { previousArticleNumber = currentArticleNumber if (currentArticleNumber >= articles.length - 1) { currentArticleNumber = 0 } else { currentArticleNumber++ } } const sendEvent = (label, action = 'Click') => { const value = `SelectelDIY — loc: Footer — ${label} — ${action}`; if (window.dataLayer !== undefined) { window.dataLayer.push({ event: 'data_event', data_description: value, }); } }; function generatedText() { let defaultText if (platform === 'Desktop') { defaultText = `Мы тут собрали %text%. Хотите научим?` } else { defaultText = `Мы тут собрали %text%.` } return defaultText.replace('%text%', articles[currentArticleNumber].text) } function getRandom(min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min } (function create() { currentArticleNumber = getRandom(0, articles.length - 1) cycle() let page = document.querySelector('.page--entry') if (page) { function insertAfter() { let parents = page.querySelectorAll('[data-id="7"]') let referenceNode = parents[0] referenceNode.parentNode.insertBefore(banner, referenceNode.nextSibling); loaded() } setTimeout(() => insertAfter(), 0) } }()) function loaded() { banner.classList.add('loaded') } loadImages([ `${cdnUrl}CameraCatDesktop.svg`, `${cdnUrl}ChillCatDesktop.svg`, `${cdnUrl}CloudCatDesktop.svg`, `${cdnUrl}CameraCatMobile.svg`, `${cdnUrl}ChillCatMobile.svg`, `${cdnUrl}CloudCatMobile.svg?3`, ]) function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); } }())
0
4 комментария
Популярные
По порядку

Когда ошибся сайтом %)

3

Чет контейнер с postgres выдает в логах 
initdb: error: superuser name "pg_user" is disallowed; role names cannot begin with "pg_"
гуглил ничего не нашел полезного :(

0

Ну там же в ошибке и написано, что нельзя использовать пользователя с префиксом pg_ нужно в .env поменять имя POSTGRES_USER=postgres
там может быть и другие ошибки с контейнером postgres:
1 - \docker-php-workspace\postgres\data нужно удалить .gitkeep
2 - environment добавить PGDATA: /tmp

0

что-то postgres не хочет запускаться((

0
Читать все 4 комментария
Будущее наступит во вторник на OneRetailConf
«Альфа-банк» не начислил корректно кешбэк и общие впечатления

Уже 2 недели ищу время на данный пост, но каждый раз банк чувствует и мешает это сделать – то в приложение не пускает, то в личный кабинет)))

HTC показала новую VR-гарнитуру — компания прифотошопила устройство к стоковым фотографиям Статьи редакции

«Трудно поверить, что ваша вещь хороша, если вам пришлось прифотошопить её к модели. Почему бы не сделать новую фотографию?», — пишет The Verge.

The Verge
Чем плох SkyEng и что лучше него в разы

Учителя-студенты по цене профессиональных тьюторов-носителей. Обман, чтобы получить оплату. Игнор просьб и требований клиента.

Сервис Почты России и как ждать курьера почти 2 недели.

Так вот рассказываю. Время подходило к отпуску , мы решили с девушкой отправится в холодный Российский городок. И я такой думаю, закажу я своей девушке костюм в Puma, сделаю приятность перед отдыхом. Залетаю на сайт , выбрал , доставка курьером 3-4 дня , кайф (на сайте не указанно каким курьером будет доставка). Пару моментов и приходит смс , что…

В Японии установили торговые автоматы со случайными авиабилетами по стране Статьи редакции

Peach Aviation не получает большой прибыли от автоматов, зато на популярности компании это сказывается хорошо.

Аппарат Peach Aviation Vice
«Spotify: История продукта». Как мы разработали алгоритмы музыкальных рекомендаций

Из онлайн-библиотеки — в сервис персонализированных рекомендаций.

Что ждет S&P500?

Ежемесячный анализ S&P500. Выпуск №9 от 14.10.2021г

Microsoft выпустит мини-холодильники в стиле Xbox Series X за $100 Статьи редакции

Предзаказы откроются 19 октября.

Мини-холодильники Xbox The Verge
Дефицит цифровых кадров в России и их подготовка

Весь мир переходит в цифровую среду. Пока в ежегодном глобальном рейтинге конкурентоспособности Россия занимает 43-е место, но задерживаться на нем не намерена. Для этого правительство запустило программу «Цифровая экономика РФ», которая будет поддерживать цифровую экономику в стране и подготовку необходимых кадров.

Объявлены победители Finlanding
null