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.
Let's immediately introduce Docker, which is the main subject.
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 **
** ② The setting screen as per the search wording is displayed **
** ③ Find the item Hyper-v in it and check it **
Now you are ready to install
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
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.
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
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.
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.
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.
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!
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.
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!
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.
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.
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.
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.
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.
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
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 user ・ Problem that cannot log in to mysql
Recommended Posts