#!/usr/bin/env sh set -e cd /home/project # 1) Bootstrap Symfony if needed if [ ! -f composer.json ]; then echo "⏳ Initializing Symfony project..." composer create-project symfony/website-skeleton . "6.3.*" fi # 2) Ensure public directory and minimal front controller mkdir -p public if [ ! -f public/index.php ]; then cat > public/index.php << 'EOL' <?php use Symfony\Component\HttpFoundation\Request; require __DIR__ . '/../vendor/autoload_runtime.php'; return function (Request $request) { echo "Symfony project initialized!"; }; EOL fi # 3) Install/update dependencies composer install --prefer-dist --no-interaction # 4) Finally, hand over to PHP’s built-in server echo "✅ Starting PHP dev server on 0.0.0.0:8000" exec php -S 0.0.0.0:8000 -t public
Step 1: Download Docker Desktop
DOWNLOAD
Confirm installation in terminal: docker --version
Step 1.1: Create your username
Step 1.2 : Login to docker from terminal
Login with username: docker login -u [USERNAME]
Step 1.3: Run these commands
docker pull mariadb:10.6 or mariadb:1doc1docker-compose -f docker-compose.dev.yml up -d
Step 2 :
Identify the .docker folder and edit the following files: Dockerfile and init.sql
Dockerfile
FROM bitnami/minideb:bullseye # ———————————————————————————————— # 1) Copy in config & init script # ———————————————————————————————— COPY .docker/php.ini /tmp/php.ini COPY .docker/jasperstarter.zip /tmp/jasperstarter.zip COPY init-symfony.sh /usr/local/bin/init-symfony.sh # ———————————————————————————————— # 2) Install base tools + JasperStarter # ———————————————————————————————— RUN apt-get update && \ apt-get install -y git wget curl unzip htmldoc default-jre && \ cd /tmp && unzip jasperstarter.zip && \ mv jasperstarter /opt/jasperstarter && \ chmod -R 755 /opt/jasperstarter # ———————————————————————————————— # 3) Add Sury PHP repo, install PHP 7.4+ + deps + Composer + Symfony CLI # ———————————————————————————————— RUN apt-get update && \ apt-get install -y apt-transport-https lsb-release ca-certificates && \ wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg && \ echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" \ > /etc/apt/sources.list.d/php.list && \ apt-get update && \ apt-get install -y \ php7.4-cli php7.4-zip php7.4-gd php7.4-xml php7.4-ldap \ php7.4-mysql php7.4-mbstring mariadb-client fonts-liberation && \ cat /tmp/php.ini >> /etc/php/7.4/cli/php.ini && \ curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/local/bin --filename=composer && \ wget -qO - https://get.symfony.com/cli/installer | bash && \ mv /root/.symfony*/bin/symfony /usr/local/bin/symfony && \ rm -rf /var/lib/apt/lists/* # ———————————————————————————————— # 4) JDBC driver for Jasper # ———————————————————————————————— RUN wget -qO /usr/share/java/mariadb-java-client.jar \ https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/2.7.3/mariadb-java-client-2.7.3.jar && \ mkdir -p /opt/jasperstarter/jdbc && \ ln -s /usr/share/java/mariadb-java-client.jar /opt/jasperstarter/jdbc/mysql.jar # ———————————————————————————————— # 5) Workdir + Entrypoint # ———————————————————————————————— WORKDIR /home/project # Make our init script executable RUN chmod +x /usr/local/bin/init-symfony.sh # On container startup, run the init script (which will bootstrap Symfony # and then exec php -S 0.0.0.0:8000 -t public) # important file to be added in root level ENTRYPOINT ["sh", "/usr/local/bin/init-symfony.sh"]
Refer to Step 2.2 to add init-symfony.sh
init.sql
-- Development database initialization -- Create and use development database CREATE DATABASE IF NOT EXISTS ind_test_dev; USE ind_test_dev; -- Grant privileges to the development user GRANT ALL PRIVILEGES ON *.* TO 'dev_user'@'%'; FLUSH PRIVILEGES; -- Run your existing build.sql USE ind_test_dev; source /docker-entrypoint-initdb.d/database/build.sql; source /docker-entrypoint-initdb.d/database/update.sql;
Step 2.2: Create init-symfony.sh:
#!/usr/bin/env sh set -e cd /home/project # 1) Bootstrap Symfony if needed if [ ! -f composer.json ]; then echo "⏳ Initializing Symfony project..." composer create-project symfony/website-skeleton . "6.3.*" fi # 2) Ensure public directory and minimal front controller mkdir -p public if [ ! -f public/index.php ]; then cat > public/index.php << 'EOL' <?php use Symfony\Component\HttpFoundation\Request; require __DIR__ . '/../vendor/autoload_runtime.php'; return function (Request $request) { echo "Symfony project initialized!"; }; EOL fi # 3) Install/update dependencies composer install --prefer-dist --no-interaction # 4) Finally, hand over to PHP’s built-in server echo "✅ Starting PHP dev server on 0.0.0.0:8000" exec php -S 0.0.0.0:8000 -t public
Step 3:
Change the file name from docker-compose.yml to docker-compose.dev.yml
Add .env.local but do not remove the .env file
APP_ENV=dev APP_DEBUG=1 DATABASE_URL=mysql://dev_user:dev_password@sqldb_dev:3306/ind_test_dev # Change the email addresses to prevent accidental sending to real addresses CADORATH_EMAIL_NOTIFY_CONSIGNMENT_UPDATE=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_INVENTORY_UPDATE=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_ERP_DAYEND=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_WORKORDER_NEWPART=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_WORKORDER_QUOTE_CHANGED=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_WORKORDER_MOVED_ENGINEERING=dev-CADORATHing@example.com CADORATH_EMAIL_NOTIFY_WARRANTY_APPROVAL=dev-CADORATHing@example.com CADORATH_EMAIL_RPI_CONTRACT_REVIEW=dev-CADORATHing@example.com CADORATH_EMAIL_RPI_PROCEDURE_APPROVAL=dev-CADORATHing@example.com LDAP_ENABLED=false
Step 4:
Create docker-compose.dev.yml and paste the below config.
Change the SQL DATABASE_URL to your local dev URL and SQL credentials in env.local
version: '3.8' services: app: container_name: weberty_dev build: context: . dockerfile: .docker/Dockerfile ports: - "127.0.0.1:8088:8000" working_dir: /home/project # ensure entrypoint starts here volumes: - ./project:/home/project:delegated depends_on: - sql environment: APP_ENV: dev APP_DEBUG: '1' DATABASE_URL: mysql://dev_user:dev_password@sqldb_dev:3306/ind_test_dev LDAP_ENABLED: 'false'
SQL:
container_name: sqldb_dev image: mariadb:11 # keep 11 if you want that version ports: - "127.0.0.1:3307:3306" volumes: - ./.docker/init.dev.sql:/docker-entrypoint-initdb.d/init.sql:ro - ./database_local:/var/lib/mysql # ? use a *fresh* folder or a named volume restart: always command: --event-scheduler=ON environment: MYSQL_ROOT_PASSWORD: devrootpass MYSQL_DATABASE: ind_test_dev MYSQL_USER: dev_user MYSQL_PASSWORD: dev_password
Step 5: Edit the following config files
project/config/cadorath.yaml: change all %env to %env.local
From
# Cadorath Aerospace specific configuration settings parameters: cadorath.id: "%env(CADORATH_ID)%" # used by legacy code cadorath.db: "%env(DATABASE_URL)%" cadorath.fqdn: "%env(CADORATH_FQDN)%" cadorath.serial: "%env(CADORATH_SERIAL)%" cadorath.locale: "%env(CADORATH_LOCALE)%" cadorath.date.format: "Y/m/d" cadorath.path.dayend: "%env(CADORATH_PATH_DAYEND)%" cadorath.path.status: "%env(CADORATH_PATH_STATUS)%" cadorath.path.document.rpi: "%env(CADORATH_PATH_DOCUMENT_RPI)%" cadorath.path.document.erp: "%env(CADORATH_PATH_DOCUMENT_ERP)%" cadorath.path.jasper.target: "%env(CADORATH_PATH_JASPER_TARGET)%" cadorath.path.jasper.source: "%env(CADORATH_PATH_JASPER_SOURCE)%" cadorath.path.report.legacy.source: "%env(CADORATH_PATH_LEGACY_REPORT_SOURCE)%" cadorath.app.smtp.host: "cadorath-com.mail.protection.outlook.com" cadorath.email.notify.consignment.update: "%env(CADORATH_EMAIL_NOTIFY_CONSIGNMENT_UPDATE)%" cadorath.email.notify.inventory.update: "%env(CADORATH_EMAIL_NOTIFY_INVENTORY_UPDATE)%" cadorath.email.notify.erp.dayend: "%env(CADORATH_EMAIL_NOTIFY_ERP_DAYEND)%" cadorath.email.notify.workorder.newpart: "%env(CADORATH_EMAIL_NOTIFY_WORKORDER_NEWPART)%" cadorath.email.notify.workorder.quote.changed: "%env(CADORATH_EMAIL_NOTIFY_WORKORDER_QUOTE_CHANGED)%" cadorath.email.notify.workorder.moved.engineering: "%env(CADORATH_EMAIL_NOTIFY_WORKORDER_MOVED_ENGINEERING)%" cadorath.email.notify.warranty.approval: "%env(CADORATH_EMAIL_NOTIFY_WARRANTY_APPROVAL)%" cadorath.email.rpi.contract.review: "%env(CADORATH_EMAIL_RPI_CONTRACT_REVIEW)%" cadorath.email.rpi.procedure.approval: "%env(CADORATH_EMAIL_RPI_PROCEDURE_APPROVAL)%"
To
# Cadorath Aerospace specific configuration settings parameters: cadorath.id: "%env.local(CADORATH_ID)%" # used by legacy code cadorath.db: "%env.local(DATABASE_URL)%" cadorath.fqdn: "%env.local(CADORATH_FQDN)%" cadorath.serial: "%env.local(CADORATH_SERIAL)%" cadorath.locale: "%env.local(CADORATH_LOCALE)%" cadorath.date.format: "Y/m/d" cadorath.path.dayend: "%env.local(CADORATH_PATH_DAYEND)%" cadorath.path.status: "%env.local(CADORATH_PATH_STATUS)%" cadorath.path.document.rpi: "%env.local(CADORATH_PATH_DOCUMENT_RPI)%" cadorath.path.document.erp: "%env.local(CADORATH_PATH_DOCUMENT_ERP)%" cadorath.path.jasper.target: "%env.local(CADORATH_PATH_JASPER_TARGET)%" cadorath.path.jasper.source: "%env.local(CADORATH_PATH_JASPER_SOURCE)%" cadorath.path.report.legacy.source: "%env.local(CADORATH_PATH_LEGACY_REPORT_SOURCE)%" cadorath.app.smtp.host: "cadorath-com.mail.protection.outlook.com" cadorath.email.notify.consignment.update: "%env.local(CADORATH_EMAIL_NOTIFY_CONSIGNMENT_UPDATE)%" cadorath.email.notify.inventory.update: "%env.local(CADORATH_EMAIL_NOTIFY_INVENTORY_UPDATE)%" cadorath.email.notify.erp.dayend: "%env.local(CADORATH_EMAIL_NOTIFY_ERP_DAYEND)%" cadorath.email.notify.workorder.newpart: "%env.local(CADORATH_EMAIL_NOTIFY_WORKORDER_NEWPART)%" cadorath.email.notify.workorder.quote.changed: "%env.local(CADORATH_EMAIL_NOTIFY_WORKORDER_QUOTE_CHANGED)%" cadorath.email.notify.workorder.moved.engineering: "%env.local(CADORATH_EMAIL_NOTIFY_WORKORDER_MOVED_ENGINEERING)%" cadorath.email.notify.warranty.approval: "%env.local(CADORATH_EMAIL_NOTIFY_WARRANTY_APPROVAL)%" cadorath.email.rpi.contract.review: "%env.local(CADORATH_EMAIL_RPI_CONTRACT_REVIEW)%" cadorath.email.rpi.procedure.approval: "%env.local(CADORATH_EMAIL_RPI_PROCEDURE_APPROVAL)%"
project/config/services.yaml
From
Symfony\Component\Ldap\Ldap: arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter'] Symfony\Component\Ldap\Adapter\ExtLdap\Adapter: arguments: - host: 192.168.1.27 port: 389 #encryption: tls options: protocol_version: 3 referrals: false
To
Symfony\Component\Ldap\Ldap: arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter'] Symfony\Component\Ldap\Adapter\ExtLdap\Adapter: arguments: - host: 127.0.0.1 port: 389 #encryption: tls options: protocol_version: 3 referrals: false
Step 6: Setup Docker Build
docker-compose -f docker-compose.dev.yml up -d sql
Step 6.1: Verify database container
docker-compose -f docker-compose.dev.yml ps
Step 7: Test Database Connection
Host: 127.0.0.1
Port: 3307
User: dev_user
Password: dev_password
Database: ind_test_dev
Step 8: Build and Start App Container
Step 8.1: Build app container
docker-compose -f docker-compose.dev.yml build app
Step 8.2: Start app container
docker-compose -f docker-compose.dev.yml up -d app
Step 8.3: Verify both containers running
docker-compose -f docker-compose.dev.yml ps
Stop app container (optional -testing only)
docker compose -f docker-compose.dev.yml down

App is successful output in terminal:
weberty_dev | 88 packages you are using are looking for funding. weberty_dev | Use the `composer fund` command to find out more! weberty_dev | weberty_dev | Run composer recipes at any time to see the status of your Symfony recipes. weberty_dev | weberty_dev | ✅ Starting PHP dev server on 0.0.0.0:8000 weberty_dev | [Thu May 1 19:48:54 2025] PHP 7.4.33 Development Server (http://0.0.0.0:8000) startedSQL is running successfully:
sqldb_dev | 2025-05-01 19:48:56 0 [Note] Server socket created on IP: '0.0.0.0'. sqldb_dev | 2025-05-01 19:48:56 0 [Note] Server socket created on IP: '::'. sqldb_dev | 2025-05-01 19:48:56 0 [Note] mariadbd: Event Scheduler: Loaded 0 events sqldb_dev | 2025-05-01 19:48:56 1 [Note] Event Scheduler: scheduler thread started with id 1 sqldb_dev | 2025-05-01 19:48:56 0 [Note] mariadbd: ready for connections. sqldb_dev | Version: '11.7.2-MariaDB-ubu2404' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
Troubleshooting:
Check container logs: docker-compose -f docker-compose.dev.yml logs app
Reset the database if needed:
docker-compose -f docker-compose.dev.yml down
rm -rf ./database_dev
mkdir -p ./database_dev
docker-compose -f docker-compose.dev.yml up -d