Skip to content

Instantly share code, notes, and snippets.

@goofansu
Last active May 18, 2023 09:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goofansu/dc310971ca5131132a6ae44998a67eee to your computer and use it in GitHub Desktop.
Save goofansu/dc310971ca5131132a6ae44998a67eee to your computer and use it in GitHub Desktop.
Rails development environment powered by Nix + Direnv
use flake
# Use binstubs directly
PATH_add bin
# Web server port
export PORT=3000
# MySQL config directory
export MYSQL_HOME=./config
### Location: bin/dev
#!/usr/bin/env sh
exec foreman start -f Procfile.dev "$@"
{
description = "dev environment";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in with pkgs; {
devShells.default = mkShell {
packages = [
# Runtimes
ruby_2_7
nodejs-16_x
# Databases
mysql80
redis
# Tools
chromedriver
imagemagick
yarn
# Dependencies
cmake
icu
libffi
libiconv
openssl
pkg-config
zlib
zstd
];
shellHook = ''
MYSQL_DATA_DIR=$PWD/mysql_data
MYSQL_SOCKET_FILE=mysql.sock
# Initialize MySQL data directory
if [ ! -d "$MYSQL_DATA_DIR" ]; then
mkdir -p $MYSQL_DATA_DIR
mysqld --initialize-insecure \
--datadir=$MYSQL_DATA_DIR \
--socket=$MYSQL_SOCKET_FILE
fi
# Create database.yml if not present
DATABASE_FILE=$PWD/config/database.yml
if [ ! -f "$DATABASE_FILE" ]; then
cp -v config/database.yml.example $DATABASE_FILE
fi
# Create my.cnf if not present
MYSQL_CONFIG_FILE=$PWD/config/my.cnf
if [ ! -f "$MYSQL_CONFIG_FILE" ]; then
cp -v config/my.cnf.example $MYSQL_CONFIG_FILE
fi
# Create Procfile.dev if not present
PROCFILE=$PWD/Procfile.dev
if [ ! -f "$PROCFILE" ]; then
cp -v Procfile.example $PROCFILE
fi
'';
};
});
}
### This file is located in ./config/my.cnf
[client]
port=3306
socket=./mysql_data/mysql.sock
[mysqld]
port=3306
bind-address=127.0.0.1
datadir=./mysql_data
socket=mysql.sock
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
web: bundle exec puma -C ./config/puma.rb
mysql: mysqld
redis: redis-server
js: ./bin/webpacker -w
dj: bundle exec rake jobs:work
sidekiq: bundle exec sidekiq -C config/sidekiq.yml
@goofansu
Copy link
Author

goofansu commented May 15, 2023

Requirement

  • Nix (Package management in a different way)
  • Direnv (Setup development env according to shell.nix when entering the project's root directory)

Steps

  1. Enable direnv
direnv allow

All necessary packages for development are installed and the MySQL data directory is created in ./mysql_data.

  1. Install gems
bundle install
  1. Start to dev with Procfile.dev
dev

That's all. Open http://localhost:3000 to visit.

You may need to setup database in another shell:

bundle exec rails db:setup

Enjoy the power of functional programming and plain old shell script!

@alper
Copy link

alper commented May 17, 2023

mysqld is already in the Procfile?

@goofansu
Copy link
Author

goofansu commented May 17, 2023

@alper Yes, it is contained in the mysql80 package. All packages are installed once direnv is enabled via direnv allow.

@alper
Copy link

alper commented May 18, 2023

I mean:

In one shell, start MySQL server

I don't think you have to start it separately if it's in the procfile?

@goofansu
Copy link
Author

@alper You're right, one can start MySQL with Procfile and then create database. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment