- Notifications
You must be signed in to change notification settings - Fork2
RunCloudIO/butler
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Butler is a replacement forLaravel Valet that works inside Docker. So, no more tinkering with brew, fixing things, etc when things go south. Since Butler is based on Laravel Valet, please take a look atLaravel Valet Documentation before using Butler.
Butler codebase is 100% taken from Laravel Valet and a few codebase was inspired (taken) fromLaravel Sail. Since Valet was designed for MacOS, a few tweak from main code need to be changed inside Butler to give the same experience as using Laravel Valet.
I hate it when things doesn't work on my machine after I have setup everything. Things just don't work sometimes and I believe you have face the same problem. When I create Butler, it is because brew service give ton shit of error. Not to mention, when upgrading your Mac sometimes you face new error.
Like every programmer, instead of fixing broken things. Why not make a new solution? I like how Laravel Valet works but to deal with errors (not causing by Laravel Valet), it just consumed my daily life experience in developing my product. To combat this, Butler was born.
To make things simple inside your development machine, Butler should make your life easy without having to install PHP, Nginx or DNSmasq inside your Mac. Thus, keeping your Mac clean and you can easily setup your development environment when you buy a new Mac with your hard earned money.
Butler aim to replicate the simplicity of using Laravel Valet and thus I will not add other cool shit feature to Butler if it does not available inside Laravel Valet. AnyPR that add a feature which not exist inside Valet willbe rejected without hesitation. This project is my first project in Docker because I want to learn how to use Docker. There will be part of this code which you will feel like an00b who wrote this project, and that is because it is. If you have any improvement to make, don't hesitate to make PR or the noob code will stay forever.
- valet share
- valet fetch-share-url
- valet unsecure --all
$ git clone https://github.com/RunCloudIO/butler.git$ cd butler$ git checkout tags/$(curl --silent "https://api.github.com/repos/RunCloudIO/butler/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')$ ./install.sh$ cd www/default$ mkdir mysite$ cd mysite$ echo "<?php phpinfo();" > index.php$ # update DNS to 127.0.0.1$ open -a "Google Chrome" http://mysite.test
Requirement:
To start with Butler, clone this repository and runinstall.sh
$ git clone https://github.com/RunCloudIO/butler.git$ cd butler$ git checkout tags/$(curl --silent "https://api.github.com/repos/RunCloudIO/butler/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')$ ./install.sh
IMPORTANT PART. After the installation succeeded, change your DNS inside System Preferences > Network > Advanced > DNS to
127.0.0.1
Failure to do sowill prevent you from running custom domain TLD.
If you havemoved the folder to a different path, simply runinstall.sh
inside the new path to make surebutler
command know about it.
To update, just
$ cd /path/to/butler$ git pull$ git checkout tags/$(curl --silent "https://api.github.com/repos/RunCloudIO/butler/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')$ ./install.sh
install.sh
command will not replace yourdocker-compose.yaml
and.env
. But if we release a new update to that compose file, you can just delete your compose file and runninginstall.sh
will re-add latestdocker-composer.yaml
.
To make your life easier, it is better to use your daily command rather than invokingbutler
directly. Before doing this, make sure you haveREMOVE Laravel Valet completely. So, here it is. Edit~/.bash_profile
and append these lines:
alias valet="butler"alias php="butler php"alias composer="butler composer"
After that,source ~/.bash_profile
and you may usevalet
,php
,composer
just like you have installed them natively.
Since your application is running inside a container, you can't use127.0.0.1
to connect to database, Redis, etc. To solve this, Butler retain the functionality from Docker for Mac where you can call host by their domain name. Inside your application, you need to change from127.0.0.1
tohost.docker.internal
to connect to host.
As stated, Butler aiming to follow Laravel Valet closely. Thus, it should be same with Laravel Valet in term of usage and experience. The only difference is, Butler use Docker rather than installing dependency usingbrew
directly into MacOS.
Butler aim to keep development machine clean without installingphp
,nginx
anddnsmasq
. That is all what Laravel Valet is doing. It doesn't matter if you want to install other tools (mysql
,redis
,supervisor
) directly inside your MacOS because it is not in Laravel Valet scope.
Laravel Sail is new development tools from Laravel. Same as Butler, it is using Docker to accomplish the task. However, Laravel Sail is aiming for per project based rather than setup once and forget everything. You also need to setup Sail for each Laravel instance that you have to make use of Sail. AndSail only works with Laravel.
If you dig down into Sail codes, you can see that it is installing every binary inside single Docker container. The problem happen when you want to launch multiple Sail instance. For each Sail instance, you need to configure different port for different project if you want to keep everything up at the same time. Although this can be solve by usingTraefik, you still need to learn how to use Traefik and configure Sail configuration to use Traefik. So, each of your Laravel Sail instance will have Traefik configuration rather than setup once (Laravel Valet) and run forever.
You will havebutler
installed inside/usr/local/bin/butler
. Thus, you can invokebutler
command anywhere.
butler
command without any argument is same as runningvalet
without any argument. You also can runbutler valet
if you prefer it that way.
Valet default path was set to/var/www/default
. So you may create your 1st project inside there, which is inside host iswww/default
directory.
$ butler start# start butler process$ butler reload# reload processes if you change .env or docker-compose.yaml$ butler reset# reset everything to original state but keep your item in mounted folder$ butler restart# restart all butler services$ butler stop# stop all butler services
Since you are not installing any PHP inside your Mac, you can run php usingbutler php
. Thus, runningphp artisan migrate
can be run usingbutler php artisan migrate
. Or if you prefer the shortest waybutler artisan migrate
, orbutler art migrate
.
Same as using composer, you can runbutler composer create-project laravel/laravel example-app
to install Laravel.
PLEASE TAKE NOTE that running PHP based command (php, valet, composer, artisan) only supported onDEFAULT_WWW_PATH
that you have set inside.env
.
Running PHP based command ouside ofDEFAULT_WWW_PATH
folder is equivalent to running the command inside/var/www/
. If you need to run outside that folder, you need to manually mount your folder and interact directly with the Docker container.
Since we are using Docker,changing PHP version iseasier than ever. You just need to update.env
by changingBUTLER_PHP_VERSION
to either version8.0, 7.4, 7.3, 7.2, 7.1, or 7.0. Then just issuebutler reload
for it to take effect.
You can only runbutler valet park
orbutler valet link
insideDEFAULT_WWW_PATH
defined in.env
. If you run these command outside theDEFAULT_WWW_PATH
directory, it will automatically run your command inside/var/www
in the container.
You may create another folder insideDEFAULT_WWW_PATH
and register it as new parked paths or linked path. So you can divide your codebase per project basis inside here. To give you the idea, take a look at the sample below.
...└── www ├── default │ ├── mysite │ │ └── index.php │ ├── mysite2 │ │ └── index.php │ └── mysite3 │ └── index.php ├── link1 │ └── index.php ├── link2 │ └── index.php ├── project1 │ ├── backend │ │ └── index.php │ └── frontend │ └── index.php └── project2 ├── backend │ └── index.php └── frontend └── index.php
Laravel Valet command
$ cd <path to DEFAULT_WWW_PATH>$ butler park default$ butler link link1$ butler link link2$ butler park project1$ butler park project2
You probably didn't like the idea of havingwww
folder inside this cloned repo. For example, you clone this project into/Users/<username>/Documents/tools/butler
and getting into thatwww
directory is too much.
To change this, you need to update.env
file andDEFAULT_WWW_PATH
to a new path, let say your Desktop. Make sure to use absolute path when definingDEFAULT_WWW_PATH
. Give it a reload (butler reload
) and check whether your site still registered with Valet, usingbutler parked
orbutler links
.
To run backend process (eg: Laravel Queue), you need process manager. Two widely known process managers areSupervisor andPM2. Youcan't run both of this process manager inside Docker container because it does not have the php binary and butler script inside the container. So both of this software need to be installed natively inside your system.
For Supervisor, you can create the config as follow:
[program:<project-name>]environment=NOTTY=truecommand=butler php artisan queue:work --tries=1directory=/path/to/laravelredirect_stderr=trueautostart=trueautorestart=trueuser=<your username>numprocs=1process_name=%(program_name)s_%(process_num)s
For PM2, you may createpm2-queue.yaml
with below content:
apps: -name:<project-name>script:NOTTY=true butler php artisan queue:work --tries=1exec_mode:forkinstances:1
Then start PM2 withpm2 start pm2-queue.yaml
It may be odd to see this package included Docker networking config with static IP Address for each services. It is needed, let me tell you why.
First of all, you can see we are runningtwo instances of DNSMasq. It needed two because, 1 is for our Mac to resolve the .test (or something else) domain and another one is for the container to resolve the .test domain.
Why do we need it? Ok, if you are running a simple PHP application, it would not make any sense in this. But, if your PHP Application call other .test domain, probably calling API, it will resolve to webserver service. Without having the internal-dns, all container will only resolve to127.0.0.1
. So, php container need to know that .test domain will be pointed to webserver service.
Check whether your site exists using either command
$ butler parked$ butler links$ butler proxies
If it does not exist, inside any, check whether the path has been loaded inside valet
$ butler paths
About
Laravel Valet using Docker