Skip to content

Commit d31b9d2

Browse files
committed
Release 1.0.0
0 parents  commit d31b9d2

10 files changed

Lines changed: 1609 additions & 0 deletions

File tree

.env.example

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Sidworks Database Sync Configuration
2+
# Copy these variables to your .env.local file and adjust the values
3+
4+
# ===== STAGING ENVIRONMENT =====
5+
SW_DB_SYNC_STAGING_HOST=staging.example.com
6+
SW_DB_SYNC_STAGING_USER=username
7+
SW_DB_SYNC_STAGING_PORT=22
8+
SW_DB_SYNC_STAGING_PROJECT_PATH=/var/www/html
9+
10+
# ===== PRODUCTION ENVIRONMENT =====
11+
SW_DB_SYNC_PRODUCTION_HOST=production.example.com
12+
SW_DB_SYNC_PRODUCTION_USER=username
13+
SW_DB_SYNC_PRODUCTION_PORT=22
14+
SW_DB_SYNC_PRODUCTION_PROJECT_PATH=/var/www/html

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Config file with local overrides
2+
sw-db-sync-config.json

README.md

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
# Sidworks Database Sync Plugin
2+
3+
A Shopware 6 plugin for syncing databases from staging/production environments to your local development environment via SSH.
4+
5+
## Features
6+
7+
- Sync from staging or production environments
8+
- SSH connection support with key authentication
9+
- Automatic database dump, download, and import
10+
- Two-step dump strategy (structure + data) for consistent snapshots
11+
- Table filtering for performance and GDPR compliance (62 tables by default)
12+
- DEFINER clause stripping for cross-server compatibility
13+
- Foreign key and unique check optimization during import
14+
- Local environment overrides (URLs, domains, system config)
15+
- Raw SQL execution post-import
16+
- Post-sync console commands (e.g. deactivate plugins, create users)
17+
- Apply config overrides without a full sync (`--apply-config-only`)
18+
- DDEV compatible
19+
- Gzip compression support
20+
- Automatic cache clearing
21+
22+
## Installation
23+
24+
#### Via Composer (Recommended)
25+
26+
```bash
27+
composer require sidworks/sw-plugin-database-sync --dev
28+
bin/console plugin:refresh
29+
bin/console plugin:install --activate SidworksDatabaseSync
30+
bin/console cache:clear
31+
```
32+
33+
#### Manual Installation
34+
35+
1. Clone or download this repository to `custom/plugins/SidworksDatabaseSync`
36+
2. Run the following commands:
37+
38+
```bash
39+
bin/console plugin:refresh
40+
bin/console plugin:install --activate SidworksDatabaseSync
41+
bin/console cache:clear
42+
```
43+
44+
## Configuration
45+
46+
### Environment Variables
47+
48+
Add the following to your `.env.local` file:
49+
50+
```bash
51+
# Staging Environment
52+
SW_DB_SYNC_STAGING_HOST=your-staging-server.com
53+
SW_DB_SYNC_STAGING_USER=your-username
54+
SW_DB_SYNC_STAGING_PORT=22
55+
SW_DB_SYNC_STAGING_PROJECT_PATH=/var/www/html
56+
SW_DB_SYNC_STAGING_KEY=~/.ssh/id_ed25519 # Optional: SSH key path
57+
58+
# Production Environment
59+
SW_DB_SYNC_PRODUCTION_HOST=your-production-server.com
60+
SW_DB_SYNC_PRODUCTION_USER=your-username
61+
SW_DB_SYNC_PRODUCTION_PORT=22
62+
SW_DB_SYNC_PRODUCTION_PROJECT_PATH=/var/www/html
63+
SW_DB_SYNC_PRODUCTION_KEY=~/.ssh/id_ed25519 # Optional: SSH key path
64+
65+
# Local overrides
66+
SW_DB_SYNC_LOCAL_DOMAIN=your-project.ddev.site
67+
SW_DB_SYNC_DOMAIN_MAPPINGS=production.com:your-project.ddev.site,staging.com:your-project.ddev.site
68+
SW_DB_SYNC_CLEAR_CACHE=true # Set to "false" to skip cache clearing
69+
```
70+
71+
#### Required Variables
72+
73+
| Variable | Description |
74+
|----------|-------------|
75+
| `SW_DB_SYNC_[ENV]_HOST` | Hostname or IP address of the server |
76+
| `SW_DB_SYNC_[ENV]_USER` | SSH username |
77+
| `SW_DB_SYNC_[ENV]_PORT` | SSH port (default: 22) |
78+
| `SW_DB_SYNC_[ENV]_PROJECT_PATH` | Remote Shopware project directory path |
79+
80+
#### Optional Variables
81+
82+
| Variable | Description |
83+
|----------|-------------|
84+
| `SW_DB_SYNC_[ENV]_KEY` | Path to SSH private key (supports `~/` expansion) |
85+
| `SW_DB_SYNC_LOCAL_DOMAIN` | Default local domain for URL overrides |
86+
| `SW_DB_SYNC_DOMAIN_MAPPINGS` | Comma-separated `from:to` domain mappings |
87+
| `SW_DB_SYNC_CLEAR_CACHE` | Clear cache after sync — `true` (default) or `false` |
88+
89+
Replace `[ENV]` with either `STAGING` or `PRODUCTION`.
90+
91+
## Advanced Configuration (Config File)
92+
93+
Create a `sw-db-sync-config.json` file in your Shopware root directory:
94+
95+
```bash
96+
cp vendor/sidworks/sw-plugin-database-sync/sw-db-sync-config.json.example sw-db-sync-config.json
97+
nano sw-db-sync-config.json
98+
```
99+
100+
When this file exists, it takes priority over environment variable domain mappings.
101+
102+
### Configuration Sections
103+
104+
#### `ignore_tables`
105+
106+
Tables to skip during the data dump. The example file includes 62 commonly ignored tables covering:
107+
108+
**Performance tables** (always recommended):
109+
- `enqueue` — Message queue
110+
- `product_keyword_dictionary` — Search keywords
111+
- `product_search_keyword` — Search index
112+
- `log_entry` — Application logs
113+
- `message_queue_stats` — Queue statistics
114+
- `elasticsearch_index_task` — Search indexing
115+
- `state_machine_history` — Order/payment state history
116+
117+
**GDPR/Privacy tables** (customer and order data):
118+
- `customer`, `customer_address`, `customer_tag`, `customer_wishlist`
119+
- `order`, `order_address`, `order_delivery`, `order_line_item`, `order_transaction`
120+
- `cart` — Shopping carts
121+
- `user`, `user_config`, `user_recovery`, `user_access_key` — Admin users
122+
- `newsletter_recipient`, `newsletter_recipient_tag`
123+
- Payment plugin tables (Klarna, Payone, Pay.nl, Unzer)
124+
125+
**Tip**: Remove tables from the list if you need them in development. For example, keep `user` if you need existing admin accounts.
126+
127+
#### `sales_channel_domains`
128+
129+
Map sales channel IDs to local domains. Find your sales channel IDs with:
130+
131+
```sql
132+
SELECT LOWER(HEX(id)) as id, name FROM sales_channel;
133+
```
134+
135+
```json
136+
{
137+
"sales_channel_domains": {
138+
"018d5f1e5e7e7f1e8b8d5f1e5e7e7f1e": "https://your-project.ddev.site"
139+
}
140+
}
141+
```
142+
143+
#### `system_config`
144+
145+
Update Shopware system configuration values after import:
146+
147+
```json
148+
{
149+
"system_config": {
150+
"core.basicInformation.email": "local@example.com",
151+
"core.mailerSettings.host": "localhost",
152+
"core.mailerSettings.port": "1025"
153+
}
154+
}
155+
```
156+
157+
Values that don't exist yet are automatically inserted.
158+
159+
#### `sql_updates`
160+
161+
Execute raw SQL statements after import. Use with caution:
162+
163+
```json
164+
{
165+
"sql_updates": [
166+
"UPDATE sales_channel_domain SET url = REPLACE(url, 'production.com', 'ddev.site')"
167+
]
168+
}
169+
```
170+
171+
#### `post_sync_commands`
172+
173+
Console commands to run after the sync completes. Failed commands produce warnings but don't abort the process:
174+
175+
```json
176+
{
177+
"post_sync_commands": [
178+
"user:create admin -a --email info@example.com -p thisIsMyPassword",
179+
"plugin:refresh",
180+
"plugin:install SidworksDatabaseSync -a",
181+
"theme:compile"
182+
]
183+
}
184+
```
185+
186+
Common use cases:
187+
- Create a local admin user after importing (since `user` table is typically ignored)
188+
- Deactivate production-only plugins or apps
189+
- Refresh and reinstall the sync plugin itself after import
190+
- Recompile themes
191+
192+
### Environment Variables vs Config File
193+
194+
| Method | Use case |
195+
|--------|----------|
196+
| Environment variables (`.env.local`) | Simple domain mappings, basic setups |
197+
| Config file (`sw-db-sync-config.json`) | Advanced overrides, system config, SQL updates, post-sync commands |
198+
199+
If `sw-db-sync-config.json` exists, it takes priority over environment variable domain mappings.
200+
201+
## Usage
202+
203+
### Basic sync from staging
204+
205+
```bash
206+
bin/console sidworks:db:sync staging
207+
```
208+
209+
### Sync from production
210+
211+
```bash
212+
bin/console sidworks:db:sync production
213+
```
214+
215+
### Options
216+
217+
| Option | Description |
218+
|--------|-------------|
219+
| `--keep-dump, -k` | Keep the dump file in `var/dumps/` after import |
220+
| `--skip-import` | Only download the dump, don't import |
221+
| `--no-gzip` | Don't compress the dump (faster for small databases) |
222+
| `--skip-overrides` | Skip applying local environment overrides |
223+
| `--no-ignore` | Dump all tables (don't ignore any) |
224+
| `--apply-config-only[=path]` | Only apply config file overrides without syncing |
225+
| `--skip-cache-clear` | Skip clearing cache after applying configuration |
226+
| `--skip-post-commands` | Skip running post-sync commands |
227+
228+
### Apply config only (no database sync)
229+
230+
Re-apply your `sw-db-sync-config.json` overrides without downloading a new database dump. Useful after manual database changes or when you just need to update system config:
231+
232+
```bash
233+
# Use default sw-db-sync-config.json
234+
bin/console sidworks:db:sync --apply-config-only
235+
236+
# Use a custom config file
237+
bin/console sidworks:db:sync --apply-config-only=custom-config.json
238+
239+
# Use an absolute path
240+
bin/console sidworks:db:sync --apply-config-only=/path/to/config.json
241+
242+
# Apply config only, skip cache clear and post-sync commands
243+
bin/console sidworks:db:sync --apply-config-only --skip-cache-clear --skip-post-commands
244+
```
245+
246+
### Verbose output
247+
248+
Show which tables are being ignored:
249+
250+
```bash
251+
bin/console sidworks:db:sync staging -v
252+
```
253+
254+
## DDEV Usage
255+
256+
If you're using DDEV, forward your SSH agent first:
257+
258+
```bash
259+
ddev auth ssh
260+
```
261+
262+
Then run the sync command inside the container:
263+
264+
```bash
265+
ddev exec bin/console sidworks:db:sync staging
266+
```
267+
268+
## How It Works
269+
270+
### Execution Flow
271+
272+
1. **Validate configuration** — Check required SSH and environment settings
273+
2. **Fetch remote `.env`** — Read database credentials from the remote server via SSH
274+
3. **Create remote dump** — Two-step mysqldump (structure + data) on the remote server
275+
4. **Download dump** — Transfer the compressed dump via rsync
276+
5. **Cleanup remote** — Delete the dump file from the remote server
277+
6. **Import database** — Import dump into local database with optimizations
278+
7. **Apply overrides** — Update domains, system config, and run SQL updates
279+
8. **Clear cache** — Run `cache:clear:all`
280+
9. **Run post-sync commands** — Execute configured console commands
281+
10. **Cleanup local** — Delete the local dump file (unless `--keep-dump`)
282+
283+
### mysqldump Strategy
284+
285+
The plugin uses a two-step dump process:
286+
287+
1. **Structure dump**: `--no-data --routines` exports table structures, triggers, stored procedures, and functions
288+
2. **Data dump**: `--no-create-info --skip-triggers` exports data only, skipping ignored tables
289+
290+
**Common flags:**
291+
- `--single-transaction` — InnoDB consistent read without table locks (safe for production)
292+
- `--quick` — Stream results without buffering entire tables
293+
- `-C` — Compress data between client and server
294+
- `--hex-blob` — Binary data as hex for portability
295+
- `--column-statistics=0` — Disable statistics collection (auto-detected if supported)
296+
297+
**Post-processing (both steps):**
298+
- `LANG=C LC_CTYPE=C LC_ALL=C` — Consistent character encoding
299+
- `sed` strips `DEFINER` clauses for cross-server compatibility
300+
301+
### Import Optimization
302+
303+
The import pipeline applies several optimizations:
304+
305+
- `SET FOREIGN_KEY_CHECKS=0` — Disables FK constraint checks during import to prevent deadlocks and speed up loading
306+
- `SET UNIQUE_CHECKS=0` — Skips unique index verification during bulk insert
307+
- `SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"` — Preserves explicit zero values in auto-increment columns
308+
- DEFINER clauses are stripped locally via `sed` before piping to `mysql`, avoiding privilege errors when views or stored procedures reference specific users
309+
- Foreign key and unique checks are re-enabled at the end of the import
310+
311+
### Override Priority
312+
313+
1. If `sw-db-sync-config.json` exists → use config file (sales channel domains, system config, SQL updates)
314+
2. Otherwise → use environment variable domain mappings (`SW_DB_SYNC_DOMAIN_MAPPINGS`)
315+
3. Fallback → use `SW_DB_SYNC_LOCAL_DOMAIN` to set all sales channel domains
316+
317+
## Troubleshooting
318+
319+
### SSH Connection Failed
320+
321+
1. **In DDEV**: Run `ddev auth ssh` to forward your SSH agent into the container
322+
2. **SSH Key**: Set `SW_DB_SYNC_[ENV]_KEY` to your private key path
323+
3. **SSH Agent**: Ensure your key is loaded: `ssh-add ~/.ssh/your_key`
324+
325+
### Permission Denied
326+
327+
Your SSH user needs:
328+
- Read access to the remote `.env` file
329+
- Execute permissions for `mysqldump`
330+
- Write permissions to `/tmp` on the remote server
331+
332+
### Remote .env Not Found
333+
334+
Verify that `SW_DB_SYNC_[ENV]_PROJECT_PATH` points to the Shopware root directory containing the `.env` file.
335+
336+
### Import Fails with DEFINER Errors
337+
338+
This is handled automatically. Both the remote dump and local import pipeline strip DEFINER clauses. If you still encounter errors, check that your MySQL user has `SUPER` or `PROXY` privileges, or verify the dump file isn't corrupted.
339+
340+
## Requirements
341+
342+
- Shopware 6.7+
343+
- PHP 8.1+
344+
- SSH access to remote servers
345+
- `mysqldump` on the remote server
346+
- `rsync` for file transfer
347+
- `gzip` / `gunzip` (unless using `--no-gzip`)
348+
349+
## Author
350+
351+
Sidworks — https://www.sidworks.nl/

composer.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "sidworks/sw-plugin-database-sync",
3+
"description": "Sidworks Plugin Database Sync",
4+
"type": "shopware-platform-plugin",
5+
"version": "1.0.0",
6+
"require": {
7+
"shopware/core": "~6.6.0 || ~6.7.0"
8+
},
9+
"license": "MIT",
10+
"authors": [
11+
{
12+
"name": "Sidworks"
13+
}
14+
],
15+
"autoload": {
16+
"psr-4": {
17+
"Sidworks\\DatabaseSync\\": "src/"
18+
}
19+
},
20+
"extra": {
21+
"shopware-plugin-class": "Sidworks\\DatabaseSync\\SidworksDatabaseSync",
22+
"label": {
23+
"en-GB": "Sidworks Plugin Database Sync"
24+
},
25+
"description": {
26+
"en-GB": "Sidworks Plugin Database Sync"
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)