docker-compose пример стека apache2, php, mysql, phpmyadmin, и проксирование nginx
Создадим с помощью Docker Compose ещё один пример, довольно часто используемый стек: сервер apache2 с php, базой данных на mysql, и контейнер для управления базой с помощью phpmyadmin, а также настроим прокси на nginx ещё в одном отдельном контейнере, чтобы было удобно всем этим пользоваться. Таким образом мы увидим всю логику происходящего, для создания подобных конфигураций, для собственных нужд.
если у вас ещё не установлены docker и docker-compose,
то в Debian подобных дистрибутивах это делается так:
Теперь приступим.
Рассмотрим всё на простом примере. Создаём каталог product с будущим проектом
mkdir product cd product
это будет корень проекта.
создаём каталоги
mkdir php mkdir html mkdir html/apache_logs mkdir mysql
создаём файлы
touch php/Dockerfile touch html/index.php touch docker-compose.yaml touch mysite.conf touch nginx.conf
Заходим внутрь каталога php (в нём мы создадим файл именно с таким именем Dockerfile, даже регистр имеет значение, это файлы для создания docker образов, на тот случай если нам нужно что-то добавить в базовый образ который мы берём из dockerhub, в этом примере мы доработаем образ для нашего php сервера)
Затем идём в каталог html
Фактически этот каталог и будет, для файлов нашего сайта, который мы планируем запустить на этом сервере, поэтому в нём сразу создаём файл index.php для тестирования работоспособности наших контейнеров.
Так же в этом же каталоге создаём подкаталог apache_logs
для логов сервера.
Выходим обратно на уровень product и создаём ещё один каталог для второго контейнера баз данных, фактически для хранения на хосте файлов с базой данных и настроек,
mysql
Теперь основное действие, здесь же на корневом уровне проекта, создаём файл для сборки контейнеров
называется вот так: docker-compose.yaml
в точности копируем, вместе с расширением yaml
Теперь создадим файл настроек apache2 который будет работать в контейнере, mysite.conf это файл конфигурации нашего сайта для сервера apache2 который мы смонтируем внутрь контейнера при его создании. В тот же контейнр мы смонтируем и каталог html
Также создаём файл nginx.conf, этот файл будет отвечать за настройку для третьего контейнера, с нашим прокси.
А во второй контейнер, с базой данных мы смонтируем каталог mysql
Как всё это будет монтироваться, мы наглядно мы увидем в содержимом файла docker-compose.yaml
А пока, сейчас у вас должна быть вот такая структура корня проекта, каталог product:
☯
Terminal:
⌕
≡
✕
. ├── nginx.conf ├── docker-compose.yaml ├── html │ ├── apache_logs │ └── index.php ├── mysite.conf ├── mysql └── php └── Dockerfile
создайте все эти файлы и каталоги, и приступим к их заполнению.
начнём с файла
docker-compose.yaml Обратите внимание все отступы, в этом файле, как и оступы в файлах Dockerfile, строго одного уровня, они имееют синтаксическое значение, почти точно такое же как и в файлах python, поэтому внимательно соблюдайте такие оступы, если желаете, чтобы у вас всё работало без ошибок.
обратите внимение, все строки которые начинаются с # можно просто удалить, они являются комментариями и никак не учитываются при сборке.
☯
Terminal:
⌕
≡
✕
version: '3' services: #первый контейнер для php и сервера apache2 php: build: context: ./php dockerfile: Dockerfile ports: #здесь мы указываем на каких портах будет работать контейнер. т.е. первым идёт порт хоста с которого мы запустим контейнер #вторым через : идёт порт внутри контейнера - '81:80' # - '25:25' volumes: # это деректива монтирования # здесь показаны вначале локальные каталоги на вашем хосте, из корня проекта, а затем через знак : каталоги где они будут расположены и как называться внутри контейнеров - ./html:/var/www/html - ./html:/usr/local/apache2/htdocs - ./html/apache_logs:/var/log/apache2 - ./mysite.conf:/usr/local/apache2/conf/extra/mysite.conf depends_on: # здесь мы указываем зависимость или связь со вторым образом, который мы назовём db и пропишем ниже - db environment: # здесь мы указываем переменную окружения, в данном случае зададим переменной DOMEN, url адрес, обратите внимаение как # эта переменная используется при создании контейнера, на локально хосте если нет домен можно использовать localhost или обращаться к серверу просто по его ip - DOMAIN=ramanzes.freemyip.com networks: # и ещё один важный параметр это внутренняя сеть, наших контейнеров по которой все они будут работать друг с другом - myapp_network #второй контейнер для сервера mysql создаём просто из образа db: image: mysql:latest volumes: - ./mysql:/var/lib/mysql environment: - MYSQL_DATABASE=base_docker - MYSQL_USER=docker - MYSQL_PASSWORD=dockerpassword - MYSQL_ROOT_PASSWORD=rootpassword networks: - myapp_network #третий контейнер для сервиса phpmyadmin, для управления базой данных, также создаём просто из образа phpmyadmin: image: phpmyadmin/phpmyadmin ports: - '8081:80' environment: - PMA_ARBITRARY=1 - PMA_HOST=db depends_on: - db networks: - myapp_network #четвёртый контейнер для сервера nginx создаём просто из образа, у нас будет работать, как прокси, это будет прописано в файле nginx.conf proxy: image: nginx:latest volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf ports: - '80:80' networks: - myapp_network #без оступа как и services начинаеся деректива сети.Для простоты я добавлю указание использования сети по умолчанию, называемой bridge. networks: myapp_network: driver: bridge
Теперь файл mysite.conf:
В котором, кстати отступы, уже не имеют синтаксического значения, только для наглядности.
Эта конфигурация будет добавлена внутрь контейнера, в момент его сборки...
☯
Terminal:
⌕
≡
✕
ServerRoot "/usr/local/apache2" #обратите внимание здесь указывается внутренний порт контейнера 80, а не внешний, что у нас тут был бы как 81ServerName ramanzes.freemyip.com DocumentRoot "/var/www/html" Options Indexes FollowSymLinks AllowOverride All Require all granted SetHandler application/x-httpd-php ErrorLog "/var/log/apache2/my_error.log" CustomLog "/var/log/apache2/my_access.log" combined
Теперь файл nginx.conf:
В котором, кстати отступы, уже не имеют синтаксического значения, только для наглядности.
Эта конфигурация будет добавлена внутрь контейнера nginx, в момент его сборки...
☯
Terminal:
⌕
≡
✕
server { # здесь также указывается внутренний порт контейнера(если бы они отличались например 83:80), т.е. второй 80 это внутренний #а не внешний из наших настроек но у нас эти порты идентичны docker-compose(80:80) listen 80; listen [::]:80; server_name localhost; #access_log /var/log/nginx/host.access.log main; # location / { # root /usr/share/nginx/html; # index index.html index.htm; # } #локация это slug, доп адрес в url после proxy_pass здесь пусто location / { #а здесь уже указываются внешние порты из нашего docker-compose(81:80 для php) внешний это 81 proxy_pass http://ramanzes.freemyip.com:81/; } #локация это slug, доп адрес в url после proxy_pass, а здесь + /phpmyadmin location /phpmyadmin { #а здесь уже указываются внешние порты из нашего docker-compose(8081:80 для phpmyadmin) внешний здесь 8081 proxy_pass http://ramanzes.freemyip.com:8081/; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} }
теперь файл ├── php
│ └── Dockerfile
Dockerfile
☯
Terminal:
⌕
≡
✕
FROM php:8.0-apache RUN apt-get update \ && apt-get install -y libpq-dev libonig-dev \ && docker-php-ext-install pdo pdo_mysql mysqli RUN apt-get install -y apache2-bin RUN a2enmod alias RUN a2enmod rewrite RUN service apache2 restart
теперь файл
├── html
│ └── index.php
Для проверки связи контейнеров, вот пример на PHP, который создает таблицу в базе данных PostgreSQL, заполняет ее случайным текстом и выводит этот текст на экран в браузере:
☯
Terminal:
⌕
≡
✕
<h1>Да php работает в It works</h1> <?php phpinfo(); ?> <?php // Подключение к базе данных $servername = "db"; $username = "docker"; $password1 = "dockerpassword"; $password2 = "rootpassword"; $dbname = "base_docker"; $conn = new mysqli($servername, $username, $password1, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Создание таблицы $sql = "CREATE TABLE IF NOT EXISTS random_text ( id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, text VARCHAR(255) NOT NULL )"; if ($conn->query($sql) === TRUE) { echo "Table 'random_text' created successfully<br><br>"; } else { echo "Error creating table: " . $conn->error; } // Заполнение таблицы случайным текстом for ($i = 1; $i <= 10; $i++) { $randomText = generateRandomText(); $sql = "INSERT INTO random_text (text) VALUES ('$randomText')"; if ($conn->query($sql) === TRUE) { echo "Inserted random text: $randomText<br>"; } else { echo "Error inserting text: " . $conn->error; } } // Вывод текста из базы данных на экран $sql = "SELECT * FROM random_text"; $result = $conn->query($sql); if ($result->num_rows > 0) { echo "<br>Random Text:<br>"; while($row = $result->fetch_assoc()) { echo $row["text"] . "<br>"; } } else { echo "No random text found"; } $conn->close(); // Функция для генерации случайного текста function generateRandomText($length = 20) { $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $randomText = ''; for ($i = 0; $i < $length; $i++) { $randomText .= $characters[rand(0, strlen($characters) - 1)]; } return $randomText; } ?>
Перед использованием этого примера необходимо заменить значения "имя_пользователя", "пароль" и "имя_базы_данных" на соответствующие данные вашей базы данных MySQL, которые вы указали при сборке контейнера в файле docker-compose.yaml. Убедитесь, что у вас есть соединение с базой данных для выполнения примера. Также учтите, что данное решение для базы данных MySQL, и вам понадобится установленный драйвер PHP для работы с MySQL, что мы уже сделали с помощью php/Dockerfile.
Приведенный пример создает таблицу 'random_text' с двумя столбцами: 'id' (идентификатор) и 'text' (текстовое поле). Затем он заполняет таблицу случайным текстом, используя функцию generateRandomText(). Наконец, он извлекает текст из базы данных и выводит его на экран в браузере.
После приведения своего рабочего каталога в такой вид, находясь в корне проекта, т.е. в том же каталоге, же где и файл docker-compose.yaml
Выполняем следующие команды по порядку. Загрузим образы на свой компьютер.
Создадим контейнеры из этих образов и запустим их, следующей командой:
Убедимся, что контейнеры запустились успешно:
Ну и понятное дело, что если вы откроете в браузере домен в моём случае это http://ramanzes.freemyip.com/, ну или localhost, который вы указали в образе php при создании web сервера, вы увидете свой сервер в работе.
http://ramanzes.freemyip.com/phpmyadmin/ или localhost/phpmyadmin/, http://your-domen/phpmyadmin/ если вы тестируете на домашнем компьютере, или ip адрес сервера xxx.xxx.xxx.xxx/phpmyadmin/ обратите внимание, что слэш на конце адреса имеет значение, и его нужно указывать, чтобы всё работало.
для того чтобы войти в phpmyadmin нужно вводить следующие данные исходя из наших настроек
-
- Roman Sakhno
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.