Following on from yesterday's post, in addtion to getting WordPress, MySQL and phpMyAdmin running from one docker-compose up
command, I wanted to run the React client accessing the WP REST API from that same command.
In order to do so, I created a Dockerfile
in the /client folder (the /client folder was created via the npx create-react-app client
command). This added the /client folder into the root directory of the project. I placed the Dockerfile within that.
The Dockerfile looks like this:
FROM node:13.6.0-alpine
# set working directory
WORKDIR /var/www/html/client
# add `/var/www/html/node_modules/.bin` to $PATH
ENV PATH /var/www/html/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /var/www/html/client/package.json
COPY package-lock.json /var/www/html/client/package-lock.json
RUN npm ci
# start app
CMD ["npm", "start"]
Furthermore, in the docker-compose.yml
file from yesterday, you add a new service called 'client'. You will notice that the I have added a React environment variable named REACT_APP_WP_API
. This is set to http://localhost:8080
because that is where the WordPress site is running from. As a result, in order to access the url with something like Axios, you will need to prefix your urls with the appropriate environment variable.
For example (Note the use of process.env.REACT_APP_WP_API
):
const res = await axios.get(`${process.env.REACT_APP_WP_API}/wp-json/wp/v2/posts`);
The reason I am no longer using the "proxy" field within React's package.json
file is because, within the container running React, there is nothing running on localhost:8080. As such, it is set in the running React app so that it refers to port 8080 on the machine running the containers' localhost. The React client will be found on http://localhost:3000
.
Granted, this approach is more verbose, than using "proxy" since you need to prefix all the urls with the environment variable.
Add the following service named 'client' to the docker-compose.yml
file:
client:
depends_on:
- wordpress
build:
context: ./client
dockerfile: Dockerfile
volumes:
- "./client:/var/www/html/client"
- "/var/www/html/node_modules"
ports:
- 3000:3000
environment:
- NODE_ENV=development
- REACT_APP_WP_API=http://localhost:8080
As a result, the entire docker-compose.yml
will looks as follows:
version: "3"
services:
# database
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
networks:
- wpsite
# phpMyAdmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin/phpmyadmin
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
networks:
- wpsite
# WordPress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
# 8000 on localhost, to 80 on container
- "8080:80"
restart: always
# ./ on local machine maps to /var/www/html on Apache, which is where WP files are stored
volumes: ["./:/var/www/html"]
environment:
# 'db' is service above. 3306 is default port on MySQL
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
networks:
- wpsite
client:
depends_on:
- wordpress
build:
context: ./client
dockerfile: Dockerfile
volumes:
- "./client:/var/www/html/client"
- "/var/www/html/node_modules"
ports:
- 3000:3000
environment:
- NODE_ENV=development
- REACT_APP_WP_API=http://localhost:8080
networks:
wpsite:
volumes:
db_data:
With this setup, you can now setup and run and entire working WordPress installation with MySQL, phpMyAdmin and a running React client with one docker-compose up
command!