{"id":77364,"date":"2026-07-04T02:47:19","date_gmt":"2026-07-04T02:47:19","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=77364"},"modified":"2026-07-04T02:47:21","modified_gmt":"2026-07-04T02:47:21","slug":"docker-compose-wordpress-mysql-using-shared-environment-variables","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/docker-compose-wordpress-mysql-using-shared-environment-variables\/","title":{"rendered":"Docker Compose: WordPress + MySQL Using Shared Environment Variables"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Create a project folder:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">mkdir wordpress-env-demo\ncd wordpress-env-demo\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create a <code>.env<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">MYSQL_DATABASE=wordpressdb\nMYSQL_USER=wpuser\nMYSQL_PASSWORD=wppassword123\nMYSQL_ROOT_PASSWORD=rootpassword123\n\nWORDPRESS_PORT=8080\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create <code>docker-compose.yml<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">services:\n  db:\n    image: mysql:latest\n    <span class=\"hljs-attr\">container_name<\/span>: wordpress_mysql\n    <span class=\"hljs-attr\">restart<\/span>: always\n    <span class=\"hljs-attr\">environment<\/span>:\n      MYSQL_DATABASE: ${MYSQL_DATABASE}\n      <span class=\"hljs-attr\">MYSQL_USER<\/span>: ${MYSQL_USER}\n      <span class=\"hljs-attr\">MYSQL_PASSWORD<\/span>: ${MYSQL_PASSWORD}\n      <span class=\"hljs-attr\">MYSQL_ROOT_PASSWORD<\/span>: ${MYSQL_ROOT_PASSWORD}\n    <span class=\"hljs-attr\">volumes<\/span>:\n      - mysql_data:<span class=\"hljs-regexp\">\/var\/<\/span>lib\/mysql\n\n  <span class=\"hljs-attr\">wordpress<\/span>:\n    image: wordpress:latest\n    <span class=\"hljs-attr\">container_name<\/span>: wordpress_app\n    <span class=\"hljs-attr\">restart<\/span>: always\n    <span class=\"hljs-attr\">depends_on<\/span>:\n      - db\n    <span class=\"hljs-attr\">ports<\/span>:\n      - <span class=\"hljs-string\">\"${WORDPRESS_PORT}:80\"<\/span>\n    <span class=\"hljs-attr\">environment<\/span>:\n      WORDPRESS_DB_HOST: db:<span class=\"hljs-number\">3306<\/span>\n      <span class=\"hljs-attr\">WORDPRESS_DB_NAME<\/span>: ${MYSQL_DATABASE}\n      <span class=\"hljs-attr\">WORDPRESS_DB_USER<\/span>: ${MYSQL_USER}\n      <span class=\"hljs-attr\">WORDPRESS_DB_PASSWORD<\/span>: ${MYSQL_PASSWORD}\n    <span class=\"hljs-attr\">volumes<\/span>:\n      - wordpress_data:<span class=\"hljs-regexp\">\/var\/<\/span>www\/html\n\n<span class=\"hljs-attr\">volumes<\/span>:\n  mysql_data:\n  wordpress_data:\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Start the containers:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose up -d\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Open WordPress:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">http:<span class=\"hljs-comment\">\/\/localhost:8080<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Now students can see how environment variables are passed into both containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check MySQL container env:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose exec db printenv MYSQL_DATABASE\ndocker compose exec db printenv MYSQL_USER\ndocker compose exec db printenv MYSQL_PASSWORD\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check WordPress container env:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose exec wordpress printenv WORDPRESS_DB_HOST\ndocker compose exec wordpress printenv WORDPRESS_DB_NAME\ndocker compose exec wordpress printenv WORDPRESS_DB_USER\ndocker compose exec wordpress printenv WORDPRESS_DB_PASSWORD\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify both containers are using the same password:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose exec db printenv MYSQL_PASSWORD\ndocker compose exec wordpress printenv WORDPRESS_DB_PASSWORD\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check how WordPress reads env and creates database config:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">docker compose exec wordpress bash -lc <span class=\"hljs-string\">'grep DB_ \/var\/www\/html\/wp-config.php'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Test MySQL login using the env variable inside DB container:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">docker compose exec db bash -lc <span class=\"hljs-string\">'mysql -u$MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE -e \"SHOW TABLES;\"'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check service-name networking between containers:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">docker compose exec wordpress bash -lc <span class=\"hljs-string\">'getent hosts db'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This works because Docker Compose creates an internal network where <code>db<\/code> becomes the hostname of the MySQL container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stop everything:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose down\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Stop and delete volumes also:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker compose down -v\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">For teaching, this is perfect. For production, avoid <code>latest<\/code>, use fixed versions like <code>wordpress:6.8-apache<\/code> and <code>mysql:8.4<\/code>, and never commit real passwords into Git.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Create a project folder: Create a .env file: Create docker-compose.yml: Start the containers: Open WordPress: Now students can see how environment variables are passed into both containers&#8230;. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[11138],"tags":[],"class_list":["post-77364","post","type-post","status-publish","format-standard","hentry","category-best-tools"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77364","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=77364"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77364\/revisions"}],"predecessor-version":[{"id":77365,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/77364\/revisions\/77365"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=77364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=77364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=77364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}