This is a Poor's Man Jenkins deploy tool.
Use this to automatically deploy a website using a git command, 1 minute after receiving a webhook from the Bitbucket repository.
- Git 2.26+
This make use of Git property
sparse-checkout
, and need Git version 2.26 or up installed in the server. See https://git-scm.com/download/linux for more info on how to update Git version on linux. - PHP
- Admin permissions to:
- Add a Cron Job
- Add SSH keys
- Bitbucket.uhub.biz project or repo admin permissions to add access SSH keys.
- Update git to last version on Ubuntu
- Add Git repository to ubuntu apt:
add-apt-repository ppa:git-core/ppa
- Update apt, and install git:
apt update; apt install git
- On you server, clone this repo or manually create a folder with the repo contents. For example
/var/www/deploy
. - Edit the file
/var/www/deploy/config.php
and setup the configuration to match your system and needs:date_default_timezone_set
: Is used to set the dates in the log files. See https://www.php.net/manual/en/timezones.php for more time zones strings.$secret
: Set the password string to use to validate the webhooks call as from your repositories server. Default is1234567
. You will need to add this secret when configuring the webhook on Bitbucket.$defaultRepoSettings['command']
: This is the default git update command. If needed, you will be able to set a different command for each individual repo added to therepos.conf
file.
- Create a webserver configuration for the deploy tool and point it to the repo
/public
folder.- Optional: Associate a domain for the deploy tool, ex.:
https://deploy.myserver.com
.
- Optional: Associate a domain for the deploy tool, ex.:
- To validate, open the deploy tool URL in a browser. You should get the following message:
Nothing to do.
The deploy tool requires a cron job to be configured to run the update.php
script every minute.
- Change to the root user:
sudo su
- Edit the crontab:
crontab -e
- Add a new job to run
deploy.php
script every minute:* * * * * /usr/bin/php /var/www/deploy/deploy.php
- Replace
/usr/bin/php
with your system PHP path. You can find it using the commandwhereis php
. - Replace
/var/www/deploy/deploy.php
with the full path for thedeplopy.php
script file.
- Replace
To let the deploy tool to be able to automatically update your sites, you need add each site repo name and folder path to the /var/www/deploy/repos.conf
repo configuration file.
For this example assume that, in Bitbucket, the site repository name is repo-test1
under the project PORJECTNAME
.
- Rename the file
repos.sample.conf
torepos.conf
. This is in JSON file format. - If do not exist, add your repository project name as an object, ex.:
PORJECTNAME
.{ "PORJECTNAME": {} }
- Under the correct project name add your repository name as an object, ex.:
repo-test1
.{ "PORJECTNAME": { "repo-test1": "" } }
- As value, paste the full path to the folder where you will be cloned the website repo.
See Website setup for more information.
{ "PORJECTNAME": { "repo-test1": "/var/www/repo-test1" } }
- Done.
The minimal repo configuration need just to include the full path to the server folder in which you cloned the website, to be able to run the default git update command configured on /var/www/deploy/config.php
file.
But you may need to run a different git command, or add another command first, or after.
To do so, instead of passing a string with the full path of the repo, you can use the following object to set the path and a custom command.
{
"path": "/var/www/repo-test2",
"command": "my_custom_command && git fetch --depth 1 && git reset --hard @{upstream}"
}
The following is an example of two repositories under the same project name PORJECTNAME
, repo-test1
with the minimal configuration , and repo-test2
with a custom command configuration.
{
"PORJECTNAME": {
"repo-test1": "/var/www/repo-test1",
"repo-test2": {
"path": "/var/www/repo-test2",
"command": "my_custom_command && git fetch --depth 1 && git reset --hard @{upstream}"
}
}
}
To be able to update a website repository, the deploy tool need SSH access to the repositories.
To do so we need to create a deploy SSH key, add the private key part the root user of the server, and add the public key part to the necessary Bitbucket projects or repos.
- Change to the root user:
sudo su
. - To generate a new SSH key run the following command:
You can change the comment to what ever make this key more identifiable to you.
ssh-keygen -t rsa -b 4096 -C "deploytool"
- You will be prompted to specify the file name:
The default location and file name should be fine for most users. Press
Enter file in which to save the key (/home/yourusername/.ssh/id_rsa):
Enter
to accept and continue. - Next, you’ll be asked to type a secure passphrase. A passphrase adds an extra layer of security. If you set a passphrase, you’ll be prompted to enter it each time you use the key to login to the remote machine.
If you don’t want to set a passphrase, press Enter.
Enter passphrase (empty for no passphrase):
- The whole interaction looks like this:
yourusername@ubuntu1804:~$ ssh-keygen -t rsa -b 4096 -C "deploytool" Generating public/private rsa key pair. Enter file in which to save the key (/home/yourusername/.ssh/id_rsa): Created directory '/home/yourusername/.ssh' . Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/yourusername/.ssh/id_rsa. Your public key has been saved in /home/yourusername/.ssh/id_rsa.pub. The key fingerprint is: SHA256:2zTTC82cFN19x69SJUcØOVdNDqcd5HGVy4c8t6V6mjg deploytool The key's randomart image is: +---[RSA 4096]----+ | +%/| | +@/| | .+*X| | . ==+=| | S + o.==+| | + o.oo. | | . . .o | | E.... | | ..oo | +----[SHA256]-----+
- To verify your new SSH key pair is generated, type:
ls ~/.ssh/id_* /home/yourusername/.ssh/id_rsa /home/yourusername/.ssh/id_rsa.pub
- That’s it. You’ve successfully generated an SSH key pair on your Ubuntu client machine
Adding the public ssh key to a project will grant access to all repositories under the project.
-
From your server, copy the public SSH key part. You can use
cat
command to print the key in screen and copy it from there:cat < ~/.ssh/id_rsa.pub
-
From Bitbucket, go to the
Settings
tab for the project or repository. -
Click
Access keys
and thenAdd key
. -
Choose the Read permission for the git operations, as you want to be sure that the remote system will not be able to write back to the Bitbucket repository.
-
Paste the key into the text box and click
Add key
.
- From Bitbucket, open the repository where you want to add the webhook.
- Click the
Repository settings
link on the left side. - From the links on the Repository settings page, click the
Webhooks
link. - Click the
Create webhook
button to create a webhook for the repository. - On the Create webhook page, enter:
- A
Name
with a short description, ex.:DeployTool
- The
URL
to the deploy tool, ex:https://deploy.myserver.com
- The
Secret
to pass to the deploy tool. See Installation for more info. Optional: If you're using a self-signed certificate and want to disable certificate verification, selectSkip certificate verification
.
- A
- To validate, click on the
Test connection
button. You should get the response200
. If you click onView details
link a popup will open with the test request and response payload. The expected response body should be the stringSuccess!
. - If necessary, check the Push even field under
Events: Repository
list. - After you entered all the necessary information for your webhook, click
Create
.
On this example we assume that the site repository includes multiple folders that we don't really need to checkout on the webserver (like /src
, /assets
, /docs
, /dev
, etc), and that the compiled version of the site is on /public
folder.
- Connect by SSH to the server.
- On a private folder (outside the webserver served folders), clone the repo without checking out the files yet, and as a shallow clone:
git clone <your-repo-clone-URL> --no-checkout --depth 1
- Enter to the newly created folder:
cd <cloned-folder>
- Initialize the sparse-checkout basic settings (this will include all files only in the root of the repo):
git sparse-checkout init --cone
- Add the relative path to the folders you want to include in the checkout (space separated),
/public
folder in this example:git sparse-checkout set public
- Checkout the files:
git checkout
- You should now see files on the repo root and only the
/public
folder checked out. - Edit your webserver configuration and add a site configuration that points directly to the
/public
folder on your site repo.
The cron tab job will take care to update your site automatically. That said, if in need, you can manually update your site repo by running the following git command by yourself:
git fetch --depth 1 && git reset --hard @{upstream}
- The
fetch --depth 1
command will pull just the last version of the files, keeping the git history 1 level deep. This is to avoid waste server space with previous versions of the files. - The
reset --hard @{upstream}
command will reset the files to the last version of the current branch
Keep in mind that this will destroy any local or temp files not part of the repository. And while this is not an issue for a static site, you may want to change the git command to match your needs.
- The deploy tool will log all update activities in daily log files with the name
deploy_[day number].log
, in the configured log folder. - Only the last 31 days logs are kept.
- If the log file for the current day number already exist, it is deleted and recreated.
The logs files will include a single line for each deploy executed, including the following information:
- Date and time
- Project Name
- Repo Name
- The repository full path in the server
- The command executed
- The command result number
- The command output
Example:
2021-07-28 11:32:03am - PROJECTNAME_repo-test1 - /var/www/repo-test1 - git fetch --depth 1 && git reset --hard @{upstream} - 0
HEAD is now at 56d5b9e Fixed typo in the site