I am deploying an app using Wordpress, php-fpm, nginx and mysql on Kubernetes. The steps I have taken are:
The database seems to be working, I can connect to it and see my tables using the following command: echo "mysql -pXXX" | kubectl exec -it <mysql-pod>
. Step 4 (ssl cert and ingress) is also working and no problem there. Creating the two pods (my app and mysql), and adding the config files result in this message when I try to access my domain:
Error establishing a database connection
I deploy mysql pod using helm through this command:
helm install --name mysql --set \
mysqlRootPassword=xxx,mysqlUser=xxx,mysqlPassword=xxx, \
mysqlDatabase=xxx,persistence.size=50Gi \
stable/mysql
Once this is deployed, the pod runs and I can access my database successfully. This is when I dump my tables data from a local .sql
file onto the created database, and when I run show tables
they all exist on the persistent storage. This part seems to be working properly.
I am deploying my wordpress app and nginx containers in one pod, for mutual persistent volume use. The deployment yaml looks like this:
wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: nginx:alpine
name: nginx
env:
- name: WP_HOST
value: wordpress
- name: DB_HOST
value: mysql:3306
- name: DB_NAME
value: xxx
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
- name: wp-config
mountPath: "/etc/nginx/conf.d"
- image: my-wordpress-php-app
name: wordpress
env:
- name: MY_DB_HOST
value: mysql:3306
- name: MY_DB_NAME
value: xxx
- name: MY_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql
key: password
- name: MY_WP_HOME
value: "https://example.com"
- name: MY_WP_SITEURL
value: "https://example.com"
- name: WP_DEBUG_LOG
value: "true"
- name: WP_DEBUG
value: "true"
ports:
- containerPort: 9000
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wordpress-volumeclaim
- name: wp-config
configMap:
name: wp-config
items:
- key: wp.conf
path: wp.conf
imagePullSecrets:
- name: regcred
I have confirmed that I can access my database through my wordpress pod by simply connecting to mysql:3306. I checked and confirmed that my app works through docker compose on a server, and the code seems fine, so we can assume the wordpress app's docker image is also doing what it should.
For reference, my config file is as follows: wp.conf
listen 80;
listen 443 ssl;
server_name $SITE_URL;
root /var/www/html;
index index.php;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip off;
types {
...
}
location xxx {
rewrite .* /index.php;
...
}
location ~ '\.php#x27; {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
...
}
location / {
autoindex off;
...
}
}
Some extra info in case it helps:
- port: 3306
targetPort: 3306
And in my wordpress service I have the following:
- name: wordpress
port: 9000
targetPort: 9000
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
I have added the mysql password as a secret with the proper yaml file and base64 value. I have also tried using the command line instead for creating the secret, and both don't change anything in the results.
Here are some logs in case it can tell anything about the problem (I couldn't find much with that regards):
Mysql pod logs
MySQL init process in progress...
Warning: Unable to load '/usr/share/zoneinfo/Factory' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/posix/Factory' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/right/Factory' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
mysql: [Warning] Using a password on the command line interface can be insecure.
MySQL init process done. Ready for start up.
Nginx container logs
[11:15:03 +0000] "GET /robots.txt HTTP/1.1" 500 262 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
10.20.0.128 - - [12:17:48 +0000] "GET / HTTP/1.1" 500 262 "-" "Python/3.6 aiohttp/3.4.4"
10.20.0.128 - - [16:04:42 +0000] "GET / HTTP/1.1" 500 262 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/x Safari/537.36"
10.20.0.128 - - [16:04:42 +0000] "GET /favicon.ico HTTP/1.1" 200 5 "https://example.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/x Safari/537.36"
Wordpress container logs
127.0.0.1 - 16:04:42 +0000 "GET /index.php" 500
127.0.0.1 - 16:04:42 +0000 "GET /index.php" 200
I personally think there is something simple missing here, but I haven't been able to point it out in the past few days. Anyone know what I'm missing here?
I solved this problem by replacing the secret I used to access my database from my wordpress pod. To confirm that the secret was the issue, I created a secret and deployed mysql
with a secret reference for MYSQL_ROOT_PASSWORD and giving the same secret reference as the db password in my wordpress pod. Since they were both using the same secret object this worked and fixed the db connection issue.
FIX: Helm automatically creates a db secret that includes all of your password / used / db name entries. Use the automatically created secret in the wordpress yaml file instead of the one you create:
helm install --name mysql-helm --set \
mysqlRootPassword=xxx,mysqlUser=xxx,mysqlPassword=xxx, \
mysqlDatabase=xxx,persistence.size=50Gi \
stable/mysql
Use the created password secret like this:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-helm
key: password