Docker based environment for new Pimcore installations.

Directory Structure

  • docker-compose.yml — all service definitions
  • docker/ — Docker build context and configuration files
    • php/
    • docker file — PHP 8.4-FPM custom image
    • pimcore-supervisor.conf — Definition of supervisory worker
    • nginx/
    • default.conf — Pimcore HTTPS vhost (port 443)
    • certificate/ — SSL Certificate (pimcore.local.crt / .key)
    • php.ini — PHP runtime configuration
    • data/ — persistent volume data (git ignored)
    • mysql/ — MySQL database files
    • redis/ — Redis AOF/RDB snapshots
    • open search/ — OpenSearch index data
  • application/ — Application source Pimcore (Symfony)
    • .env — default environment variables (committed)
    • .env.local — local replacement (not performed)
    • .docker/
    • supervisord.conf — optional Supervisord replacement

Service

  • php (pimcore_php) — Custom Dockerfile — PHP 8.4-FPM + Supervisor Worker
  • nginx (pimcore_nginx) — nginx:stable — HTTPS reverse proxy
  • db (pimcore_db) — mysql:8.0 — Application database
  • redis (pimcore_redis) — redis:7-alpine — Cache / session (2 GB LRU)
  • rabbitmq (pimcore_rabbitmq) — rabbitmq:3-management — Message broker
  • open search (pimcore_opensearch) — opensearchproject/opensearch:2.11.0 — Full text search
  • Mercure (pimcore_mercure) — dunglas/mercure — Real time SSE hub

All containers share a named bridge network pimcore. Service hostname (db, redisetc.) are resolved automatically in it.

Harbor

  • 443 — Nginx — HTTPS Pimcore
  • 5672 — RabbitMQ — AMQP
  • 15672 — RabbitMQ — Management UI (guest / guest)
  • 9201 — Open Search — REST API

Configuration File

docker-compose.yml

services:
  php:
    build:
      context: ./docker
      dockerfile: php/Dockerfile
    container_name: pimcore_php
    command: >
      bash -c "
        mkdir -p /var/www/html/var /var/www/html/public/var &&
        chown -R www-data:www-data /var/www/html/var /var/www/html/public/var &&
        chmod -R 775 /var/www/html/var /var/www/html/public/var &&
        /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
      "
    volumes:
      - ./app:/var/www/html
      - ./docker/php.ini:/usr/local/etc/php/php.ini:ro
      - ./app/.docker/supervisord.conf:/etc/supervisor/conf.d/pimcore.conf:ro
    depends_on: [db, redis, opensearch]
    environment:
      - APP_ENV=prod
    networks: [pimcore]

  nginx:
    image: nginx:stable
    container_name: pimcore_nginx
    ports:
      - "443:443"
    volumes:
      - ./app:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./docker/nginx/certs:/etc/nginx/certs:ro
    depends_on: [php]
    networks: [pimcore]

  db:
    image: mysql:8.0
    container_name: pimcore_db
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: pimcore
      MYSQL_USER: pimcore
      MYSQL_PASSWORD: pimcore
    volumes:
      - ./docker/data/mysql:/var/lib/mysql
    networks: [pimcore]

  redis:
    image: redis:7-alpine
    container_name: pimcore_redis
    command: redis-server --maxmemory 2gb --maxmemory-policy allkeys-lru
    volumes:
      - ./docker/data/redis:/data
    networks: [pimcore]

  rabbitmq:
    image: rabbitmq:3-management
    container_name: pimcore_rabbitmq
    ports:
      - "5672:5672"
      - "15672:15672"
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    networks: [pimcore]

  opensearch:
    image: opensearchproject/opensearch:2.11.0
    container_name: pimcore_opensearch
    environment:
      - discovery.type=single-node
      - plugins.security.disabled=true
      - OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g
    volumes:
      - ./docker/data/opensearch:/usr/share/opensearch/data
    ports:
      - "9201:9200"
    networks: [pimcore]

  mercure:
    image: dunglas/mercure:latest
    container_name: pimcore_mercure
    environment:
      SERVER_NAME: ":80"
      MERCURE_PUBLISHER_JWT_KEY: "YOUR_JWT_SECRET_KEY"
      MERCURE_SUBSCRIBER_JWT_KEY: "YOUR_JWT_SECRET_KEY"
      MERCURE_EXTRA_DIRECTIVES: |
        anonymous
        cors_origins *
    networks: [pimcore]

networks:
  pimcore:

Change YOUR_JWT_SECRET_KEY to a long random string — must match MERCURE_JWT_KEY in the app/.env.local.

docker/php/Dockerfile

FROM php:8.4-fpm

RUN apt-get update && apt-get install -y --no-install-recommends 
    git unzip libicu-dev libzip-dev libpng-dev libjpeg-dev libfreetype6-dev 
    libwebp-dev libonig-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev 
    libpq-dev libssl-dev librabbitmq-dev graphviz supervisor 
    && rm -rf /var/lib/apt/lists/*

RUN docker-php-ext-configure gd --with-jpeg --with-webp --with-freetype 
    && docker-php-ext-install pdo pdo_mysql intl zip gd opcache bcmath soap xsl exif

RUN pecl install redis && docker-php-ext-enable redis
RUN pecl install amqp && docker-php-ext-enable amqp

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY php.ini /usr/local/etc/php/php.ini
COPY php/pimcore-supervisor.conf /etc/supervisor/conf.d/pimcore.conf

WORKDIR /var/www/html

RUN printf '#!/bin/shnexec su -s /bin/sh www-data -c "php /var/www/html/bin/console $*"n' 
    > /usr/local/bin/pimcore && chmod +x /usr/local/bin/pimcore

CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]

docker/php.ini

memory_limit=2G
max_execution_time=300
upload_max_filesize=512M
post_max_size=600M

opcache.enable=1
opcache.memory_consumption=512
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0

realpath_cache_size=4096k
realpath_cache_ttl=600

Arrange opcache.validate_timestamps=1 in development so code changes take effect without restarting the container.

docker/php/pimcore-supervisor.conf

[program:php-fpm]
command=/usr/local/sbin/php-fpm --nodaemonize
autostart=true
autorestart=true
priority=1
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:messenger-consume]
command=php /var/www/html/bin/console messenger:consume 
  pimcore_generic_data_index_queue scheduler_generic_data_index 
  pimcore_core pimcore_maintenance pimcore_scheduled_tasks pimcore_image_optimize 
  --memory-limit=512M --time-limit=3600
numprocs=3
autostart=true
autorestart=true
user=www-data
priority=10
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:consume-asset-update]
command=php /var/www/html/bin/console messenger:consume pimcore_asset_update 
  --memory-limit=512M --time-limit=3600
numprocs=1
autostart=true
autorestart=true
user=www-data
priority=10
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:consume-execution-engine]
command=php /var/www/html/bin/console messenger:consume pimcore_generic_execution_engine 
  --memory-limit=512M --time-limit=3600
numprocs=1
autostart=true
autorestart=true
user=www-data
priority=10
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

[program:maintenance]
command=bash -c 'sleep 3600 && exec php /var/www/html/bin/console pimcore:maintenance'
autostart=true
autorestart=true
user=www-data
priority=10
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true

docker/nginx/default.conf

server {
    listen 80;
    server_name _;
    return 301 
}

server {
    listen 443 ssl default_server;
    server_name _;

    ssl_certificate     /etc/nginx/certs/pimcore.local.crt;
    ssl_certificate_key /etc/nginx/certs/pimcore.local.key;

    root  /var/www/html/public;
    index index.php;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
    gzip_min_length 1000;
    gzip_comp_level 4;
    gzip_vary on;
    gzip_proxied any;

    location /hub {
        rewrite ^/hub(.*)$ /.well-known/mercure break;
        proxy_pass 
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding on;
    }

    location = /admin  { return 302 /pimcore-studio/login; }
    location = /admin/ { return 302 /pimcore-studio/login; }

    location ~ "image-thumb__[0-9]+__" {
        try_files /var/tmp/thumbnails$uri /index.php$is_args$args;
        expires max;
        add_header Cache-Control "public, immutable";
        log_not_found off;
    }

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index.php(/|$) {
        client_max_body_size 600m;
        fastcgi_pass   php:9000;
        fastcgi_split_path_info ^(.+.php)(/.*)$;
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param  HTTPS on;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_read_timeout 300;
    }

    location ~ .php$ { return 404; }

    location ~* .(jpg|jpeg|png|gif|webp|svg|css|js|ico|xml)$ {
        try_files $uri /index.php$is_args$args;
        expires max;
        log_not_found off;
    }
}

application/.env

Commit to safe placeholder values:

APP_ENV=dev
APP_DEBUG=true

APPLICATION_SECRET=CHANGE_ME_APPLICATION_SECRET_KEY_LONG_ENOUGH_FOR_VALIDATION

DATABASE_URL=mysql://pimcore:pimcore@db:3306/pimcore

PIMCORE_ADMIN_USER=admin
PIMCORE_ADMIN_PASSWORD=admin

PIMCORE_OPENSEARCH_DSN=opensearch://opensearch:9200

PIMCORE_MESSENGER_TRANSPORT_DSN_PREFIX=amqp://guest:guest@rabbitmq:5672/%2f/
RABBITMQ_DSN=amqp://guest:guest@rabbitmq:5672/%2f

MERCURE_JWT_KEY=CHANGE_ME_THIS_IS_MY_SECRET_KEY_THAT_IS_LONG_ENOUGH_FOR_VALIDATION
MERCURE_URL=
MERCURE_SERVER_URL=

app/.env.local

Created only on the server — never committed:

APP_ENV=prod
APP_DEBUG=false

# Generate with: openssl rand -hex 32
APPLICATION_SECRET=<your-random-secret>

PIMCORE_BASE_URL=

# Must match MERCURE_PUBLISHER_JWT_KEY in docker-compose.yml
MERCURE_JWT_KEY=<same-key-as-docker-compose>

New Instance Setup

1. Clone the repository

git clone <repo-url> pimcore-docker
cd pimcore-docker

2. Create application/.env.local

Copy the template above and fill in the actual values.

3. Generate an SSL certificate

mkdir -p docker/nginx/certs
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 
  -keyout docker/nginx/certs/pimcore.local.key 
  -out    docker/nginx/certs/pimcore.local.crt 
  -subj "/CN=pimcore.local"

For the original domain, place your CA signature .crt And .key in the docker/nginx/certs/ and update default.conf.

4. Build and start the container

docker compose up -d --build

Wait ~30 seconds, then verify all services are displayed Up:

docker compose ps

5. Install Composer dependencies

docker exec pimcore_php composer install --no-dev --optimize-autoloader --no-interaction -d /var/www/html

6. Install Pimcore (first run only)

docker exec pimcore_php pimcore pimcore:install 
  --admin-username=admin --admin-password=admin 
  --mysql-host-socket=db --mysql-database=pimcore 
  --mysql-username=pimcore --mysql-password=pimcore 
  --no-interaction

On the next deployment, run the migration:

docker exec pimcore_php pimcore doctrine:migrations:migrate --no-interaction

7. Install assets, warm cache, build index

docker exec -u www-data pimcore_php php /var/www/html/bin/console assets:install --symlink
docker exec -u www-data pimcore_php php /var/www/html/bin/console cache:warmup --env=prod
docker exec -u www-data pimcore_php php /var/www/html/bin/console generic-data-index:update-index-settings --all

8. Verification

  • — Pimcore admin login
  • — RabbitMQ UI (guest / guest)
  • — OpenSearch REST API

General Orders

# Logs
docker compose logs -f
docker compose logs -f php

# Console commands (as www-data)
docker exec pimcore_php pimcore <command>

# Shell access
docker exec -it pimcore_php bash

# Clear cache
docker exec -u www-data pimcore_php php /var/www/html/bin/console cache:clear

# Restart workers after a code change
docker compose restart php

# Reload Nginx without downtime
docker exec pimcore_nginx nginx -s reload

# Rebuild PHP image after Dockerfile changes
docker compose up -d --build php

# Stop everything
docker compose down

# Wipe all data (destructive)
docker compose down && rm -rf docker/data/mysql docker/data/opensearch docker/data/redis

Solution to problem

The container will not start — check logs:

docker compose up --build
docker compose logs php

502 Bad Gate — PHP may still be in the initialization process. Check supervisor:

docker exec pimcore_php supervisorctl status

All programs should be displayed RUNNING. If php-fpm show FATAL:

docker exec pimcore_php supervisorctl tail php-fpm

Database rejected — MySQL takes 20–30 seconds on first boot. Watch until “ready for connection”:

docker compose logs -f db

Permission error on var/:

docker exec pimcore_php bash -c 
  "chown -R www-data:www-data /var/www/html/var /var/www/html/public/var && 
   chmod -R 775 /var/www/html/var /var/www/html/public/var"

The OpenSearch index is empty after import — check workers and queues:

docker exec pimcore_php supervisorctl status messenger-consume:*
docker exec pimcore_php pimcore messenger:stats

That ./app directory already mounted in bind — PHP file edits will take effect immediately. Dockerfile or supervisor configuration changes are required docker compose up -d --build php.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Similar Posts