Installation
Run composer require ekyna/digital-ocean-bundle and register the bundle in AppKernel.php (or config/bundles.php for Symfony 4+).
new Ekyna\Bundle\DigitalOceanBundle\EkynaDigitalOceanBundle(),
Configuration
Add your DigitalOcean API token, Space credentials, and default Space name in config/packages/ekyna_digital_ocean.yaml:
ekyna_digital_ocean:
api:
token: "%env(DIGITAL_OCEAN_API_TOKEN)%"
spaces:
-
name: "my-do-cdn" # Must match DO Space name
region: "ams3"
key: "%env(DO_SPACE_KEY)%"
secret: "%env(DO_SPACE_SECRET)%"
usage:
bundles: "my-do-cdn" # Default Space for asset deployment
First Use Case
Deploy assets from a Symfony bundle (e.g., AcmeDemoBundle) to your DO Space:
php bin/console assets:install public
php bin/console ekyna:digital-ocean:assets:deploy
Note: This purges the entire CDN cache—use cautiously in production.
Asset Deployment
ekyna:digital-ocean:assets:deploy command to sync public/ (or custom paths) to your DO Space.public/ path by extending the command or using a custom service.
# config/packages/ekyna_digital_ocean.yaml
usage:
assets_path: "storage/app/public" # Alternative source
Flysystem Integration
ekyna_digital_ocean.{space_name}.filesystem) into services for direct file operations:
use League\Flysystem\FilesystemInterface;
class MyService {
public function __construct(
private FilesystemInterface $doSpace
) {}
}
Environment-Specific Configs
%env() for secrets and vary configs per environment (e.g., dev.yaml, prod.yaml):
# config/packages/ekyna_digital_ocean/dev.yaml
spaces:
- name: "dev-my-do-cdn"
region: "nyc3"
Event-Driven Deployments
# .github/workflows/deploy.yml
- name: Deploy to DO Space
run: php bin/console ekyna:digital-ocean:assets:deploy
Cache Purge Warning
deploy command invalidates the entire CDN cache. For granular control:
Space Name Mismatch
name in config must exactly match the DO Space name (case-sensitive). Verify with:
curl -X GET "https://api.digitalocean.com/v2/spaces" -H "Authorization: Bearer $DO_API_TOKEN"
Permissions Issues
php bin/console debug:container | grep "ekyna_digital_ocean"
Look for League\Flysystem\Filesystem errors if misconfigured.Symfony 5+ Kernel
config/bundles.php:
return [
// ...
Ekyna\Bundle\DigitalOceanBundle\EkynaDigitalOceanBundle::class => ['all' => true],
];
Enable Flysystem Logging
Add to config/services.yaml:
parameters:
flysystem.log: true
Check logs for failed operations (e.g., monolog channel).
Dry Run Extend the command to simulate deployments without uploading:
// src/Command/DryRunDeployCommand.php
class DryRunDeployCommand extends DeployCommand {
protected function execute(InputInterface $input, OutputInterface $output): int {
$this->simulateDeployment($output);
return Command::SUCCESS;
}
}
Custom Filesystem Adapter Extend the bundle to support additional DO features (e.g., lifecycle rules):
// src/DependencyInjection/EkynaDigitalOceanExtension.php
public function load(array $configs, ContainerBuilder $container) {
$container->setParameter('ekyna_digital_ocean.custom_adapter', MyCustomAdapter::class);
}
Pre/Post-Deploy Hooks
Subscribe to the ekyna.digital_ocean.deploy event:
// src/EventListener/DeployListener.php
class DeployListener {
public function onDeploy(DeployEvent $event) {
// Run custom logic (e.g., notify Slack)
}
}
Multi-Space Workflows Dynamically switch Spaces per environment:
# config/packages/ekyna_digital_ocean/prod.yaml
usage:
bundles: "prod-my-do-cdn"
How can I help you explore Laravel packages today?