Automated Deployment Configuration for 1C-Bitrix
Manual deployment of changes to a production server via FTP takes 15–30 minutes of work, risks omitting a file, and risks failing to clear the cache. With three developers on the team, version conflicts become a constant problem. Automated deployment through CI/CD solves all three issues: changes reach the server via git push, cache is cleared automatically, and deployment history is preserved.
Bitrix Limitations for Auto-Deployment
Bitrix complicates standard deployment with several peculiarities:
Cannot deploy /bitrix/ — the core updates only through the built-in update mechanism. Deploying core code via git will break the licensing mechanism and updates.
upload/ should not be in git — these are user files that change at runtime.
OPcache must be cleared — without this, PHP continues to execute old bytecode.
Agents and migrations — if deployment includes database schema changes, execution order matters.
Repository Structure
/ (repository root)
├── local/
│ ├── components/ — custom components
│ ├── modules/ — custom modules
│ ├── php_interface/ — init.php, events
│ └── templates/ — site templates
├── bitrix/
│ ├── templates/ — templates only (if not in local/)
│ └── php_interface/ — dbconn.php (WITHOUT passwords, via .env)
├── .gitignore
└── deploy/
├── post-deploy.sh
└── migrate.php
In .gitignore:
/bitrix/modules/
/bitrix/components/
/bitrix/wizards/
/upload/
/bitrix/.settings.php
/bitrix/php_interface/dbconn.php
GitHub Actions for Deployment
.github/workflows/deploy.yml:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy via SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
set -e
cd /var/www/bitrix
# Save current commit for rollback
git log -1 --format="%H" > /tmp/previous_commit
# Get changes
git fetch origin main
git checkout main
git pull origin main
# Update dependencies if composer.lock changed
if git diff HEAD~1 --name-only | grep -q composer.lock; then
composer install --no-dev --optimize-autoloader
fi
# Reset OPcache
php /var/www/bitrix/deploy/opcache_reset.php
# Clear Bitrix cache
php /var/www/bitrix/deploy/clear_cache.php
echo "Deploy completed: $(git log -1 --format='%h %s')"
Deployment Scripts
/var/www/bitrix/deploy/opcache_reset.php:
<?php
// Run only from localhost or via CLI
if (PHP_SAPI !== 'cli' && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1') {
exit(1);
}
opcache_reset();
echo "OPcache reset OK\n";
/var/www/bitrix/deploy/clear_cache.php:
<?php
$_SERVER['DOCUMENT_ROOT'] = '/var/www/bitrix';
define('NO_KEEP_STATISTIC', true);
define('NO_AGENT_CHECK', true);
define('DisableEventsCheck', true);
define('BX_WITH_ON_AFTER_EPILOG', false);
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
// Clear all managed cache
$cache = \Bitrix\Main\Data\ManagedCache::getInstance();
$cache->cleanAll();
// Reset module options cache
$GLOBALS['USER_FIELD_MANAGER'] = false;
echo "Cache cleared OK\n";
Rollback on Error
In the deploy script after deployment, add a site availability check:
# Check that site responds with 200
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" https://example.ru/)
if [ "$HTTP_CODE" != "200" ]; then
echo "Deploy failed, rolling back..."
PREVIOUS=$(cat /tmp/previous_commit)
git checkout $PREVIOUS
php /var/www/bitrix/deploy/opcache_reset.php
echo "Rolled back to $PREVIOUS"
exit 1
fi
Database Migrations
For database schema changes — a migration script that runs during deployment:
// deploy/migrate.php
<?php
require_once '/var/www/bitrix/bitrix/modules/main/include/prolog_before.php';
$applied = \Bitrix\Main\Config\Option::get('custom', 'migrations_applied', '');
$applied = $applied ? explode(',', $applied) : [];
$migrationsDir = '/var/www/bitrix/local/migrations/';
$migrations = glob($migrationsDir . '*.php');
sort($migrations);
foreach ($migrations as $file) {
$name = basename($file, '.php');
if (!in_array($name, $applied)) {
echo "Applying migration: $name\n";
require_once $file;
$applied[] = $name;
}
}
\Bitrix\Main\Config\Option::set('custom', 'migrations_applied', implode(',', $applied));
echo "Migrations done\n";
Migrations are files like 2024_03_15_add_product_index.php with SQL and PHP operations in alphabetical order.







