Setting up Magento on docker (with nginx as reverse proxy)

Download Bitnami’s Magento docker image

curl -sSL https://raw.githubusercontent.com/bitnami/containers/main/bitnami/magento/docker-compose.yml > docker-compose.yml
docker-compose up -d

You may want to change the external port within the yml file since it defaults to port 80 and 443. Here we use port 1234 for HTTP and 1235 for HTTPS.

version: '2'
services:
  mariadb:
    image: docker.io/bitnami/mariadb:10.4
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - MARIADB_USER=bn_magento
      - MARIADB_DATABASE=bitnami_magento
    volumes:
      - 'mariadb_data:/bitnami/mariadb'
  magento:
    image: docker.io/bitnami/magento:2
    ports:
      - '1234:8080' # HTTP
      - '1235:8443' # HTTPS
    environment:
      - MAGENTO_HOST=localhost
      - MAGENTO_DATABASE_HOST=mariadb
      - MAGENTO_DATABASE_PORT_NUMBER=3306
      - MAGENTO_DATABASE_USER=bn_magento
      - MAGENTO_DATABASE_NAME=bitnami_magento
      - ELASTICSEARCH_HOST=elasticsearch
      - ELASTICSEARCH_PORT_NUMBER=9200
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
    volumes:
      - 'magento_data:/bitnami/magento'
    depends_on:
      - mariadb
      - elasticsearch
  elasticsearch:
    image: docker.io/bitnami/elasticsearch:7
    volumes:
      - 'elasticsearch_data:/bitnami/elasticsearch/data'
volumes:
  mariadb_data:
    driver: local
  magento_data:
    driver: local
  elasticsearch_data:
    driver: local

Configure nginx

Sample nginx.conf that configures nginx to be a reverse proxy for docker with SSL certs from LetsEncrypt.

http {
	server {
		listen       443 ssl;
		listen [::]:443 ssl;
		server_name  yourdomain.com;

		ssl_certificate      "C:\Certbot\live\yourdomain.com\fullchain.pem";
		ssl_certificate_key  "C:\Certbot\live\yourdomain.com\privkey.pem";

		ssl_session_cache    shared:SSL:1m;
		ssl_session_timeout  5m;

		ssl_ciphers  HIGH:!aNULL:!MD5;
		ssl_prefer_server_ciphers  on;

		location / {

			proxy_pass         https://localhost:1235;
			proxy_set_header    Host               yourdomain.com;

			proxy_buffer_size          128k;
			proxy_buffers              4 256k;
			proxy_busy_buffers_size    256k;
		}
	}
}

Remember to restart nginx for settings to apply

Configure Magento

Configure hostname

Within Docker Desktop, go to Containers and click on the Magento container. In the container’s terminal, enter these to set the hostname.

magento setup:store-config:set --base-url="http://yourdomain.com/"
magento setup:store-config:set --base-url-secure="https://yourdomain.com/"

You need to do this because Magento uses full URLs for links within their pages, which breaks if you use the default localhost value.

Enable HTTPS for the admin panel

Within Docker Desktop, go to Containers and click on the mariadb container. In the container’s terminal..

mysql -u bn_magento -p bitnami_magento

Press enter when prompted for password

update core_config_data set value = 1 where path = 'web/secure/use_in_adminhtml';

Restart the Magento container

Make PHP tmp folder writeable

Within Docker Desktop, go to Containers and click on the Magento container. In the container’s terminal..

chmod 777 /opt/bitnami/php/tmp

This is so that you can upload media via the REST API without error.

Allow encoded slashes for Apache

Go to the Magento container and edit the file /opt/bitnami/apache/conf/vhosts/magento-https-vhost.conf

Add a line AllowEncodedSlashes NoDecode to the virtual host like so

<VirtualHost 127.0.0.1:8443 _default_:8443>
  ServerName www.example.com
  ServerAlias *
  SSLEngine on
  SSLCertificateFile "/opt/bitnami/apache/conf/bitnami/certs/server.crt"
  SSLCertificateKeyFile "/opt/bitnami/apache/conf/bitnami/certs/server.key"
  DocumentRoot /opt/bitnami/magento
  AllowEncodedSlashes NoDecode
  <Directory "/opt/bitnami/magento">
    Options -Indexes +FollowSymLinks -MultiViews
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>

This is to let the API passthrough paths that has the slash encoded in it. See Github issue.

Then run

apachectl restart

to apply the directive.

Never see. Never know.

Leave a Comment

Your email address will not be published. Required fields are marked *