When I tried to build an environment of PHP7.4 + Apache + MySQL with Docker, I got stuck [Windows & Mac]

"Introduction"

This time, I would like to use Docker to build ** Laravel + Apache + MySQL development environment **. Since the team including beginner programmers develops individually, the policy is to adopt simple introduction methods and procedures that are visually easy to understand.

"Introduction of Docker"

Let's immediately introduce Docker, which is the main subject.

Is Hyper-v enabled (Windows only)

Before installing Docker, you need to enable a virtualization function called Hyper-v. It seems that this function is only installed in Windows Pro series, and in other cases, it is necessary to install other virtualization technology such as VirtualBox.

** ① Enter "Turn Windows features on or off" in the "Enter here to search" section to the right of the Windows button **

image.png

** ② The setting screen as per the search wording is displayed ** image.png

** ③ Find the item Hyper-v in it and check it ** image.png

Now you are ready to install

If the Hyper-v platform is not checked in step ③

If you are mainly using your own PC, you may not be able to check it, and when you check it, it seems that you have to enable the function itself from the BIOS screen. If you get the same phenomenon, search for "Motherboard manufacturer name" BIOS Hyper-v "and you'll find an article on how to enable it. By the way, I am a GIGABYTE motherboard, so the following article was helpful.

-What to do if "Hyper-V cannot be installed" is displayed

Install Docker Desktop

Please download the installer that suits your environment from the link below.

-Installer when using Mac -Installer when using Windows 10 (pro)

After downloading, follow the steps to install without thinking. There will be a screen to select something, but basically you don't have to mess with anything.

It will be restarted when the installation is completed, so please close any other open apps etc.

After reboot

Execute the following command from the terminal on Mac or the command prompt on Windows.

docker -v

After execution, if the following version is displayed, the installation is complete.

PS C:\Users\Kohei Takahashi> docker -v
Docker version 19.03.13, build 4484c46d9d

[Exception] When an error message is displayed from Docker Desktop when restarting

The error I got wasn't exactly the same as mine, but in my case I got the error "Don't kernel Linux". Basically, if the link is displayed with the error message, you can jump to the link and the solution will be described carefully, so please proceed as it is.

Install Docker Compose

Docker has the concept of containers, and Docker Compose is a tool that makes those containers easy to handle. How to install

-[Docker] Install Docker and Docker Compose on Windows 10 Pro 64bit -How to install Docker and docker-compose on Mac

The above article is easy to understand.

Actually build the environment using Docker

This time, as mentioned above, we will prepare the environment of Laravel (PHP) + Apache + MySQL! If you are developing a team, one person can do the work from here, and the others can skip to "Launch Docker". It seems that there are no restrictions on the folder structure, but the structure is as shown in Reference. Create folders and files in your favorite directory with the following configuration.


├── docker/
│   ├── app/
│   │   ├ Dockerfile
│   │   ├ php.ini #File for PHP settings
│   │   └ 000-default.conf  #Apache configuration file
│   └── db/
│        ├ data/ #Directory for storing MySQL data
│        └ my.cnf  #MySQL configuration file
│
├── src/ #Directory for storing Laravel sources
└── docker-compose.yml

Very beautiful.

Next, we will bring the configuration files we have just prepared to life.

Dockerfile First, let's bring the Dockerfile to life.

#What kind of docker image to use for building
FROM php:7.4-apache

#Load the configuration file into PHP and Apache in the docker container
ADD php.ini /usr/local/etc/php/
ADD 000-default.conf /etc/apache2/sites-enabled/

#Install Composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

#Middleware installation
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim \
libpng-dev \
libpq-dev \
&& docker-php-ext-install pdo_mysql

#Enable modRewrite required by Laravel
RUN mv /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled
RUN /bin/sh -c a2enmod rewrite

This is also a round pakuri of Reference. It seems that these commands are executed in order from the top.

000-default.conf Then bring the Apache config file to life.

<VirtualHost *:80>
       ServerAdmin webmaster@localhost
       DocumentRoot /var/www/html/laravelapp/public
       ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
       <Directory /var/www/html/laravelapp/public>
           AllowOverride All
       </Directory>
</VirtualHost>

For "laravel app" that appears here, enter the name of the Laravel app you plan to create.

php.ini Next is php.ini


[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

I think you can understand this without explanation, but it defines the character code and "I'm Japanese, so I'm dealing with Japan."

my.cnf The last configuration file is my.cnf


[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4

This is mainly the character code setting.

Docker Compose for easy container management

When I wrote the directory structure earlier, there were "app directory" and "db directory" directly under docker, but they are [container](https://cn.teldevice.co.jp/column/10509/ "title" It was easy to understand to separate "). We create an app container and a db container, and there is a Docker Compose that can manage them easily. The Docker Compose configuration file is docker-compose.yml. Please describe the following in docker-compose.yml.

#Compose file version specification
version: '3'
#What kind of container to launch
services:
 #Container to run laravel
 app:
   #Which port to open and connect. The following opens port 80 of the container and connects to port 8000 of the host
   ports:
     - "8000:80"
   #Specify to build a container using the Dockerfile created earlier
   build: ./docker/app
   #Specify the name of the container
   container_name: laravel_app
   #Specify where to synchronize the container and host directories. Where the laravel source will go
   volumes:
     - ./src:/var/www/html
 #Container that runs MySQL
 db:
   #MySQL 5 from Docker Hub.Designation to download the official image of 7
   image: mysql:5.7
   container_name: laravel_db
   #Specify the environment variable in the container. If you pass an environment variable, there is a Docker image that will be set at build time, so it is good to check it on the Docker Hub site when using it.
   environment:
     MYSQL_ROOT_PASSWORD: root
     MYSQL_DATABASE: laravel_db
     MYSQL_USER: laravel_user
     MYSQL_PASSWORD: laravel_pass
     TZ: 'Asia/Tokyo'
   #Command at startup
   command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
   #Directory synchronization. The configuration file and the location where the MySQL data is saved are synchronized. Basically, even if the container is changed at startup, the data will be lost when the container itself stops, so it is necessary to synchronize what you want to save with the host machine.
   volumes:
     - ./docker/db/data:/var/lib/mysql
     - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
   ports:
     - 3306:330

This completes the configuration files. Let's launch Docker!

Launch Docker

When you execute the following command, the contents of docker-compose.yml described earlier will become a container.

docker-compose build

Next, let's start the container with the following command

docker-compose up

This will start it. However, when I start it with the above command, the log is always displayed because it is not executed in the background. It's annoying, so basically run the following command to start it.

docker-compose up -d

It will now run in the background.

By the way, if you want to drop it

docker-compose down

It will fall.

Create a Laravel project

Next, let's actually create a Laravel project inside the container!

Enter the shell of the app container created earlier with the following command

docker exec -it laravel_app bash

Create a project by entering the following familiar commands at the destination

composer create-project "laravel/laravel=~6.0" --prefer-dist laravelapp

Enter the project name you want to develop in the part where "laravel app" is written above.

After running, wait for a while until the project is created!

Go to the Welcome page

I wrote the following in docker-compose.yml earlier

Excerpt from app container settings


services:
 app:
   ports:
     - "8000:80" #Important here
   build: ./docker/app
   container_name: laravel_app
   volumes:
     - ./src:/var/www/html

In the description about the app container, I set a property called "ports", which is a port as its name suggests, and when you launch the docker container, you can actually go to see the laravel project created at the following URL. I can do it.

http://localhost:8000

If you can confirm with this, you can create a laravel project on Docker for the time being.

[Exception] I don't know what it is, but when Permission is denied

When I first accessed it, I was told something like this

The stream or file "/var/www/html/dooga/storage/logs/laravel.log" could not be opened in append mode: failed to open stream: Permission denied

After investigating, it seems that the apache user does not have write permission for the Laravel log file, so it is not possible to write to the log and an exception occurs.

chmod -R 777 /var/www/html/laravel_app/storage

I was able to solve it with the above command, but I don't like it. After searching for a few hours I found this article When I tried to follow the procedure immediately, it was displayed wonderfully. I'm a little wondering if this user right is good, but I think it's within the range of no problem.

[Exception] When the artisan command cannot be used

When I hit the artisan command, I got the following error

Failed to clear cache. Make sure you have the appropriate permissions.

If this happens, please check the folder structure below.

├─app #Probably not relevant this time
│  └─public
├─framework
│  ├─cache
│  │  └─data
│  ├─sessions
│  └─views
└─logs #Probably not relevant this time

Is there something wrong with the procedure, or is it not possible to make it in the first place? For unknown reasons, the contents of the above folder "framework" were not complete. I think there wasn't a folder called framework in the first place. Perhaps I didn't make something that I could make because I didn't have write permission. In my environment, these solutions successfully led me to the Welcome page.

Set the DB

Finally, it is the DB setting. These settings are organized in a file called .env. Please change as follows.

DB_CONNECTION=mysql
DB_HOST=laravel_db
DB_PORT=3306
DB_DATABASE=laravel_db  # docker-compose.yml MYSQL_DATABASE
DB_USERNAME=laravel_user  # docker-compose.yml MYSQL_DATABASE
DB_PASSWORD=laravel_pass  # docker-compose.yml MYSQL_PASSWORD

As you may be familiar with, this is the value set as "environment" in the db container in docker-compose.yml. A DB is also created at startup, so let's actually migrate after setting.

Go into the shell of the app container as before. Link start! !! Purururururune! !! (SAO style)

docker exec -it laravel_app bash

You are now in / var / www / html. If you execute ls here, you can see that there is laravel_app directly under it.

cd laravel_app # laravel_Go to app
php artisan migrate #execute migrate

If the following log is displayed after executing the above command, the migration is successful. It can be said that the environment construction has been completed once.

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.1 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (0.06 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.03 seconds)

This time it is a migration by checking the connection, so in my case I will restore it after this.

php artisan migrate:refresh

This will return you to the state before migration.

[Exception] I don't know what it is, but Access is denied

In the above, it looks like it's finished smoothly, but of course that's not the case, and I got stuck for a moment here as well. The reason is that I got an Access denied error when php artisan migrate.

Error message


root@xxxxxxxxxxxx:/var/www/html/laravel_app# php artisan migrate #Run migrate

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [1045] Access denied for user 'laravel_user'@'172.21.0.3' 

why? I actually went to see the contents of mysql In that case, once get out of the app container

docker exec it laravel_db mysql -u root -p
Enter password:  #Probably OK with root

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.31 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

You can now log in to mysql as the root user. After that, I will go to see the existing users.

mysql> select user from mysql.user;

Then, in my case, the user of laravel_db was not created. (Maybe it's natural w)

db:
   image: mysql:5.7
   container_name: laravel_db
   environment:
     MYSQL_ROOT_PASSWORD: root
     MYSQL_DATABASE: laravel_db
     MYSQL_USER: laravel_user #This user did not exist
     MYSQL_PASSWORD: laravel_pass
     TZ: 'Asia/Tokyo'
   command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
   volumes:
     - ./docker/db/data:/var/lib/mysql
     - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
   ports:
     - 3306:330

If so, you can change the .env file as the user who always uses root, but I would like to use the laravel_user user, and using root normally would result in the death penalty for religious reasons.

Now create a laravel_user with the same privileges as root! (White eyes)

Yes, then I feel like I can use root, but please keep in touch.

mysql> CREATE USER 'laravel_user'@'%' IDENTIFIED BY 'laravel_pass';

Laravel_user will be created by the above CREATE. Now give it the same privileges as root.

mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'laravel_user'@'%' WITH GRANT OPTION;

Grant permissions to laravel_user with this naughty statement. Make sure you really have the same privileges as root.

mysql> select host,user,select_priv,create_priv,insert_priv,grant_priv,account_locked from mysql.user;
+-----------+---------------+-------------+-------------+-------------+------------+----------------+
| host      | user          | select_priv | create_priv | insert_priv | grant_priv | account_locked |
+-----------+---------------+-------------+-------------+-------------+------------+----------------+
| localhost | root          | Y           | Y           | Y           | Y          | N              |
| localhost | mysql.session | N           | N           | N           | N          | Y              |
| localhost | mysql.sys     | N           | N           | N           | N          | Y              |
| %         | root          | Y           | Y           | Y           | Y          | N              |
| %         | laravel_user  | Y           | Y           | Y           | Y          | N              |
+-----------+---------------+-------------+-------------+-------------+------------+----------------+
5 rows in set (0.00 sec)

You are now free from this spell.

"Summary"

This completes the environment construction of Laravel + Apache + MySQL with Docker. Personally, I hit the wall too often and it wasn't smooth, but I'm happy because I've reached the stage where I can develop it for the time being. I would like to expand this environment a little more, so I will write about it again! 【Related article】 ・ Why don't you include Vue.js in Docker's Laravel! !!

Then

Reference material

It is a reference material that was very helpful. -Set permissions for Laravel properly -Laravel 5.7, hitting php artisan cache: clear will result in Failed to clear cache. Make sure you have the appropriate permissions. .. -ERROR 1045 (28000): What to do when Access denied for userProblem that cannot log in to mysql

Recommended Posts

When I tried to build an environment of PHP7.4 + Apache + MySQL with Docker, I got stuck [Windows & Mac]
I tried to make an introduction to PHP + MySQL with Docker
I tried to build the environment of PlantUML Server with Docker
I tried to build an environment using Docker (beginner)
How to build an environment of [TypeScript + Vue + Express + MySQL] with Docker ~ Vue edition ~
I tried to build the environment of WSL2 + Docker + VSCode
I tried to build an http2 development environment with Eclipse + Tomcat
I tried to build an API server with Go (Echo) x MySQL x Docker x Clean Architecture
I built a rails environment with docker and mysql, but I got stuck
I tried to build a Firebase application development environment with Docker in 2020
[Rails] How to build an environment with Docker
[First environment construction] I tried to create a Rails 6 + MySQL 8.0 + Docker environment on Windows 10.
[Error resolution] Occurs when trying to build an environment for spring with docker
When I bcrypt with node + docker, I got an error
I got an error when trying to install sbt to build a Scala development environment
How to build [TypeScript + Vue + Express + MySQL] environment with Docker ~ Express ~
I tried to build the environment little by little using docker
I tried to create a padrino development environment with Docker
I was addicted to WSl when trying to build an android application development environment with Vue.js
I got an IllegalAccessError when trying to use PowerMock with JUnit
How to build [TypeScript + Vue + Express + MySQL] environment with Docker ~ MySQL edition ~
Prepare a transcendentally simple PHP & Apache environment on Mac with Docker
How to build Rails + Vue + MySQL environment with Docker [2020/09 latest version]
How to build [TypeScript + Vue + Express + MySQL] environment with Docker ~ Sequelize ~
I tried to build a laravel operating environment while remembering Docker
What I was addicted to when updating the PHP version of the development environment (Docker) from 7.2.11 to 7.4.x
[Terraform] When I try to build an Azure resource on a Windows machine, it will time out, so I solved it with Docker.
Build an environment with Docker on AWS
How to build Rails 6 environment with Docker
Build an environment of "API development + API verification using Swagger UI" with Docker
After all I wanted to preview the contents of mysql with Docker ...
I installed WSL2 without using Microsoft Store and tried to build an environment where Docker can be used
I tried to verify AdoptOpenJDK 11 (11.0.2) with Docker image
Self-hosting with Docker of AuteMuteUs in Windows environment
[First team development ②] Build an environment with Docker
I got stuck when port forwarding with VBox
I built a CentOS 8 environment with Vagrant and tried to sync_folder, but I got an error, so I solved it.
When I tried to reproduce Progate's Rails app on my PC (local environment), I got stuck at the image display
How to install Docker in the local environment of an existing Rails application [Rails 6 / MySQL 8]
A story that got stuck with an error during migration in docker PHP laravel
The procedure I did when I prepared the environment of gradle + Java with VS Code (Windows 10)
[Road _node.js_1-1] Road to build Node.js Express MySQL environment using Docker
How to build docker environment with Gradle for intelliJ
I started MySQL 5.7 with docker-compose and tried to connect
Build ruby debug environment with VS Code of Windows 10
[Note] I suddenly can't build with Docker for windows.
Rails6 I tried to introduce Docker to an existing application
Build Rails (API) x MySQL x Nuxt.js environment with Docker
Webdrivers :: BrowserNotFound: Failed to find Chrome binary. When I was trying to test E2E with Docker + Rails for the first time, I got stuck in an error.
When I tried to run Azure Kinect DK with Docker, it was blocked by EULA
I tried to create a java8 development environment with Chocolatey
Easy environment construction of MySQL and Redis with Docker and Alfred
I got an InvalidUseOfMatchersException when using any with JUnit Mock
How to use mysql with M1 mac Docker preview version
Build a Node-RED environment with Docker to move and understand
docker-compose.yml when you want to keep mysql running with docker
[Vagrant] Prepare LAMP development environment with Vagrant (centos + apache + MySQL + PHP)
I tried running WordPress with docker preview on M1 Mac.
How to build an environment with Docker, which is the minimum required to start a Rails application
I tried to make a machine learning application with Dash (+ Docker) part2 ~ Basic way of writing Dash ~
Build docker environment with WSL