Tmux, is well.., tmux. Tmuxinator makes it manageable, but the "layout" definition is far from readable, and copying errors from history to your clipboard, is a true pain in the ass.
I still recommend taking a look at PM2 if you need more than "get things running". It comes with a lot of options, but that also means that your config script comes with some verbosity.
This article explains how I cover my simple use cases. Those that don't require additional file watchers (see PM2), or split panes to separate logs while sticking to a single terminal (see Tmux). For those, I use Procfiles.
No fear, Procfile is here!
Procfile? Yeah, the first time I heard it I was "not another make file, right?!". And luckily, it's nothing like that. Let's get started.
So a Procfile is a simple
key: command format. And much like a Dockerfile, it's by convention named after the format. I recommend creating file named
Procfile in the root of your project, and commit it to your repo. If not for yourself, than for every new contributor that one day joins your team.
For MagicBell, our procfile looks as follows:
server: bin/rails s -p 3000 -e development worker: bin/bundle exec sidekiq webpack: bin/webpacker-dev-server
That's it. That's all the config you need to get multiple services up and running through a single command.
npm install it to the dependencies of my node projects.
So, go ahead, and install
node-foreman. For the sake of this howto, let's go global. Drop the
-g if you have a concrete project at hand.
npm i -g node-foreman
Node-foreman installs a binary named
nf. With this installed, it's as simple as running
nf start in the same directory as your
Procfile. Try it, and see all your services spin up and log to the same terminal. When you have an
.env file in the same directory,
node-foreman automatically loads all environment variables from it. If your env file is named differently, say
.env.development, you can specify it with the
--env flag. Use the
--procfile flag if you need to specify a Procfile.
A bit more… tabs
The above might be all you need. But sometimes, I like to have my startup process a bit personalised. For that, I use scripts that I store under my home directory.
For MagicBell, my config exists of two files. One custom procfile, saved as
server: bin/rails s -p 3000 -e development worker: bin/bundle exec sidekiq webpack: bin/webpacker-dev-server codegen: yarn codegen -w
And the "executable" script that I run, saved as
~/scripts/start-magicbell (don't forget to
#!/usr/bin/env bash cd ~/dev/magicbell/backend ttab docker-compose up bundle install yarn install yarn db:migrate nf start -j ~/scripts/magicbell.proc -e .env.development
When read that script, you'll notice
ttab. ttab is a small utility that allows us to start commands in a new terminal tab. That way, I can start postgres & redis in one terminal instance (tab) while running everything else in another. Ttab is optional, but I highly recommend using it for simplicity.
npm i -g ttab
As I've added
~/scripts to my
PATH, I can get the MagicBell environment up and running using a single
start-magicbell command. Let me walk you trough wat it does:
- first, it navigates to the git repo on my drive, at
docker-compose upin a new tab, detached from the current
- installs all ruby gems, while the db is spinning up
- installs all node modules
- runs our database migration script
- starts the four services defined in the procfile
With this single command, I've started 6 services and ran some install/migrate commands. It happened too often that I manually had to install new gems or modules after pulling changes. Those commands are fast enough to run as part of my startup, yet take enough time for the database to be online before the server starts.