Bash scripts for packaging Magento2 projects and deploying it as releases on any server.
Before Deployment
- Package project to project.tar.gz with
package.sh
- Upload project.tar.gz to remote location like S3
On Deployment
deploy.sh
is triggered on deploy server- Artefact is downloaded and extracted to releases/build_2020010202002
vendor/bin/install.sh
in releases/build_2020010202002 is triggered- Hooks in releases/build_2020010202002/deploy/${ENVIRONMENT}/ are triggered
- All good -> Symlink releases/current to extracted folder releases/build_2020010202002
./scripts/package.sh \
--source-dir "${PWD}/tests/workspace/releases/build_dummy/" \
--build 99 \
--git-revision 37ed7a1 \
--filename project.tar.gz
./scripts/deploy.sh \
--package-url "tests/workspace/artifacts/project.tar.gz" \
--target-dir /workspace/tests/workspace/ \
--environment staging
Triggers composer install (vendor/bin/install.sh)
Hint: env variables and additional parameters will be passed to vendor/bin/install.sh
# Pass parameters to vendor/bin/install.sh script
./scripts/deploy.sh \
--package-url "artifacts/project.tar.gz" \
--target-dir "/var/www" \
--environment staging \
--shared-dir "/var/shared" \
--skip-systemstorage-import
./scripts/install.sh \
--project-root "${PWD}/tests/workspace/releases/build_dummy" \
--environment staging
./scripts/cleanup.sh \
--releases-dir "${PWD}/tests/workspace/releases/" \
--releases-to-keep 5
Add magento2-deployscripts to Magento 2 project
composer require ambimax/magento2-deployscripts=^1.0.0
Add configure hooks to your project (see Hooks)
mkdir -p deploy/{production,staging}/;
{ echo '#!/usr/bin/env bash'; echo "\n\necho 'hook:pre-install:triggered'"; } > deploy/{production,staging}/pre-install.sh;
When project is ready for deployment it must be packaged
Argument | Description |
---|---|
-f | --filename | Filename (i.e. projectA.tar.gz) |
-s | --source-dir | Source folder /project_root |
-t | --target-dir | Target folder (i.e. artifacts/) |
-b | --build | Build number |
-g |--git-revision | GIT revision (i.e. 37ed7a1) |
--exclude-file | File for separating package / extra package files |
--dump-config | Dump config before packaging |
--skip-di-compile | Skip comiling dependency injections before packaging |
--skip-static-content-deploy | Skip generating static content before packaging |
--skip-extra-package | Skip generating extra package |
--ignore-exclude-file | Ignore exclude file |
--save-filelist | Save filenames into text file |
./scripts/package.sh \
--source-dir "${PWD}/tests/workspace/releases/build_dummy/" \
--build 99 \
--git-revision 37ed7a1 \
--filename project.tar.gz
Files are saved to artifacts/
directory and can be uploaded either to the server or any other location
# Upload to s3 storage
aws s3 cp artifacts/project.tar.gz s3://bucket/builds/$(BUILD_NUMBER)/project.tar.gz
aws s3 cp artifacts/project.extra.tar.gz s3://bucket/builds/$(BUILD_NUMBER)/project.extra.tar.gz
aws s3 cp artifacts/MD5SUMS s3://bucket/builds/$(BUILD_NUMBER)/MD5SUMS
# or deployment server
scp artifacts/MD5SUMS \
artifacts/project.tar.gz \
artifacts/project.extra.tar.gz \
user@example.com:/home/project/builds/$(BUILD_NUMBER)/
Separation of files in package.tar.gz and package.extra.tar.gz is configured by an exclude file:
.gitignore
.git
dev/
test/
LICENSE.txt
By default this file is expected at deploy/tar_excludes.txt
- otherwise the location must be defined with --exclude-file /deploy/file.txt
To package all files into a single artifact use --ignore-exclude-file
parameter.
If packages are available it can be deployed
Argument | Description |
---|---|
-e | --environment | Environment (i.e. staging, production) |
-p | --package-url | Package url (https, S3 or local file) |
-t | --target-dir | Target dir (root of releases/ and current/) |
--install-extra-package | Also download and install .extra.tar.gz package |
--aws-profile | AWS profile name |
--wget-args | Wget arguments like --wget-args "--user=USERNAME --password=PASSWORD" |
Pass arguments to deployscript: | |
-p |--project-root | Project dir - will be set by CURRENT_RELEASE_DIR (i.e. /releases/build_2020202020) |
-s |--shared-dir | Shared dir (root of pub/media/ and var/log/) |
--skip-systemstorage-import | Skip systemstorage import |
Pass arguments to deployscript
Environment variables and unused parameters will be send to vendor/bin/install.sh
# From s3 storage
./scripts/deploy.sh \
--package-url "s3://bucket/builds/$(BUILD_NUMBER)/project.tar.gz" \
--target-dir /var/www/staging \
--environment staging
# On same server
./scripts/deploy.sh \
--package-url "/home/project/builds/$(BUILD_NUMBER)/project.tar.gz" \
--target-dir /var/www/staging \
--environment staging
# With additional parameters for vendor/bin/install.sh
./scripts/deploy.sh \
--package-url "/home/project/builds/$(BUILD_NUMBER)/project.tar.gz" \
--target-dir /var/www/staging \
--environment staging
--shared-dir "/var/shared" \
--skip-systemstorage-import
Argument | Description |
---|---|
-e | --environment | Environment (i.e. staging, production) |
-r | --project-root | Project root / extracted release folder /.../releases/build_20210201 |
-s |--shared-dir | Shared folder /.../shared/ |
Install script is triggered during deployment and environment variables and unused arguments are passed.
The following hooks are triggered during install.sh
# | Hook | Location |
---|---|---|
1 | pre | deploy/${ENVIRONMENT}/pre.sh |
2 | defaultvalidation * | deploy/${ENVIRONMENT}/defaultvalidation.sh |
2 | pre-install | deploy/${ENVIRONMENT}/pre-install.sh |
2 | install * | deploy/${ENVIRONMENT}/install.sh |
2 | post-install | deploy/${ENVIRONMENT}/post-install.sh |
2 | cleanup | deploy/${ENVIRONMENT}/cleanup.sh |
*) Replaces default behaviour
#!/usr/bin/env bash
# file: deploy/production/pre-install.sh
echo "hook:pre-install:triggered"
echo "Is production environment" || error_exit "Command not working"
Prints colored error message and exits with 1
cd bin/ || error_exit "Error Message"
Prints colored headline
info "Verify checksums"
# verify checksums...
Validates source and creates a symlink from source to destination. If destination exists, it will be removed.
# Create symlink from release/build_2020202020/pub/media to shared/pub/media
symlinkSharedDirectory "pub/media"
# Create symlink from release/build_2020202020/generated to shared/generated
symlinkSharedDirectory "generated"
# Create symlink from release/build_2020202020/var/log to shared/var/log
symlinkSharedDirectory "var/log"
Wait for a command or connection to succeed
Parameter | Description |
---|---|
--command | Set command |
--host | Set hostname |
--port | Set port |
--timeout | Set port |
# Test command
waitFor --command "/script.sh" --timeout 5
# Test tcp port
waitFor --host www.google.com --port 443 --timeout 1
Remove old deployments
Argument | Description |
---|---|
-r | --releases-dir | Releases root folder /../releases/ |
-n | --releases-to-keep | Number of builds to keep |
--dry-run | Enable dry run mode |
# Remove old deployments except for last 5
./scripts/cleanup.sh \
--releases-dir "${PWD}/tests/workspace/releases/" \
--releases-to-keep 5
MIT