{"id":3757,"date":"2020-08-03T14:23:00","date_gmt":"2020-08-03T20:23:00","guid":{"rendered":"http:\/\/benincosa.com\/?p=3757"},"modified":"2020-08-03T14:23:00","modified_gmt":"2020-08-03T20:23:00","slug":"increasing-upload-sizes-with-the-nginx-ingress-controller-kubernetes-for-wordpress-sites","status":"publish","type":"post","link":"https:\/\/benincosa.com\/?p=3757","title":{"rendered":"Increasing Upload Sizes with the Nginx Ingress Controller Kubernetes for WordPress Sites"},"content":{"rendered":"\n<p>Previously I had installed wordpress pods on Kubernetes and it made it very easy to administer and add multiple sites for clients.  However, as time went on they started getting more aggressive in the different themes they were uploading.  To solve the problem required configuration changes in two places. <\/p>\n\n\n\n<ul><li>The Ingress Controller<\/li><li>The PHP file on the WordPress pod itself. <\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Ingress Controller<\/h2>\n\n\n\n<p>The first clue that the ingress controller was having issues was that the wordpress pods I&#8217;m running are using Apache.  So I knew it was something in the Nginx Ingress controller because the error stated: <\/p>\n\n\n\n<p><code>413 Request Entity Too Large<\/code><\/p>\n\n\n\n<p>Fixing this was a matter of changing the nginx configmap for the ingress controller.  To do this it&#8217;s a simple matter of typing the following: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl edit cm -n ingress-nginx nginx-configuration<\/code><\/pre>\n\n\n\n<p>Once in here, I noticed that there was no customization so I had to create a <code>data<\/code> section.  I used the following values, which probably increased it a little too much and so I brought them lower.  Here is the example: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: v1\ndata:\n  client-body-buffer-size: 32M\n  proxy-body-size: 1G\n  proxy-buffering: \"off\"\n  proxy-read-timeout: \"600\"\n  proxy-send-timeout: \"600\"\nkind: ConfigMap\nmetadata:\n  labels:\n    app.kubernetes.io\/name: ingress-nginx\n    app.kubernetes.io\/part-of: ingress-nginx\n  name: nginx-configuration\n  namespace: ingress-nginx<\/code><\/pre>\n\n\n\n<p>Increasing the read and write timeouts allows larger files more time to upload.  Increasing the body size is what really allows large files.  You probably want something less than 1Gb.  The <a href=\"http:\/\/nginx.org\/en\/docs\/http\/ngx_http_core_module.html#client_body_buffer_size\">client-body-buffer-size<\/a> allows us to use more memory instead of writing temp files while the file is uploaded. <\/p>\n\n\n\n<p>With this in place the client was able to try uploading again, but now was confronted with a problem on the actual wordpress pod. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Updating PHP params on wordpress<\/h2>\n\n\n\n<p>By examining the logs in wordpress we saw: <\/p>\n\n\n\n<p><code>PHP Warning: \u00a0POST Content-Length of 14982910 bytes exceeds the limit of 8388608 bytes <\/code><\/p>\n\n\n\n<p>Here we are running into a PHP limit.  Through trial and error I saw I needed to increase two different parameters: <\/p>\n\n\n\n<ul><li><code>upload_max_filesize<\/code> &#8211; the max size the upload could be<\/li><li><code>post_max_size<\/code> &#8211; the max size the body could be. <\/li><\/ul>\n\n\n\n<p>If we weren&#8217;t using Kubernetes, it would be simple to go into each server, change the param in the <code>php.ini<\/code> file and then restart, but that&#8217;s not how we work in the container world.  We need it to be reproducible.  Similarly for using <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/\">ConfigMaps<\/a> in the Nginx Ingress controller, we can use ConfigMaps in our WordPress application as well. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create custom-ini ConfigMap<\/h3>\n\n\n\n<p>We are using the container for our wordpress instances called <code>wordpress:5.2-apache<\/code>.  We can see where the config files are by logging into the server:<\/p>\n\n\n\n<p><code>kubectl exec -it -n wordpress wordpress-6bc44c5c69-zjr6z -- \/bin\/bash<\/code><\/p>\n\n\n\n<p>After we can run the <code>env | grep PHP<\/code> we see that <code>PHP_INI_DIR<\/code> is set to <code>\/usr\/local\/etc\/php<\/code>.  So all we need to do is create a <code>custom.ini<\/code> file and put it into the <code>.\/conf.d<\/code> directory in that path and our changes will be activated.  Our configMap code is below: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: custom-ini\n  namespace: wordpress\ndata:\n  custom.ini: |\n    upload_max_filesize = 60M\n    post_max_size = 60M<\/code><\/pre>\n\n\n\n<p>We are using the wordpress namespace and calling this configMap <code>custom-ini<\/code>.  <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Updating the Deployment<\/h3>\n\n\n\n<p> In our deployment file we will add this configMap as a mount option.  We are using secrets files for keeping the passwords to connect to the MySQL pod as well, so there are more than one configMaps in here, but that is a post for another time.  The important parts are the following: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>       volumeMounts:\n        - name: wordpress-persistent-storage\n          mountPath: \/var\/www\/html\n        - name: config-volume\n          mountPath: \/usr\/local\/etc\/php\/conf.d\/custom.ini\n          subPath: custom.ini<\/code><\/pre>\n\n\n\n<p>   We mount the wordpress blog in persistent storage so changes persist on reboots.  Under this we add a new volumeMount and call it our config-volume.  This will show the path where this file is to be mounted.  The <code>subPath<\/code> option <a href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/volumes\/#using-subpath\">allows us to use this configMap to have other configurations elsewhere in the pod<\/a>.  <\/p>\n\n\n\n<p>The <code>config-volume<\/code> still needs to reference the <code>ConfigMap<\/code> it is referring to, so we need the following: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>volumes:\n      - name: wordpress-persistent-storage\n        persistentVolumeClaim:\n          claimName: wp-pv-claim\n      - name: config-volume\n        configMap:\n          name: custom-ini<\/code><\/pre>\n\n\n\n<p>The persistentVolumeClaim was already there, but underneath we add the configMap to reference the settings. <\/p>\n\n\n\n<p>Now with a simple apply we can update the container.  The container will reset but all changes will still remain because we use persistent volumes.  <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>kubectl apply -f custom-ini.yaml\nkubectl apply -f wordpress-deployment.yaml<\/code><\/pre>\n\n\n\n<p>The changes should now be seen in the new container if you log in and the user can now upload their giant themes. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously I had installed wordpress pods on Kubernetes and it made it very easy to administer and add multiple sites for clients. However, as time went on they started getting more aggressive in the different themes they were uploading. To solve the problem required configuration changes in two places. The Ingress Controller The PHP file&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[797],"tags":[798,941,942,930],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3757"}],"collection":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3757"}],"version-history":[{"count":1,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3757\/revisions"}],"predecessor-version":[{"id":3758,"href":"https:\/\/benincosa.com\/index.php?rest_route=\/wp\/v2\/posts\/3757\/revisions\/3758"}],"wp:attachment":[{"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benincosa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}