Last active
January 5, 2026 01:59
-
-
Save leondmello/83a984ef8ec57519048405479364f944 to your computer and use it in GitHub Desktop.
Cloud init file to set up Rails dev environment
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #cloud-config | |
| # Rails Development VM Setup | |
| # Usage: multipass launch --name rails-dev --cloud-init this-file.yaml | |
| # CONFIGURABLE VERSIONS | |
| # Edit these to change what gets installed | |
| write_files: | |
| - path: /tmp/versions.conf | |
| content: | | |
| RUBY_VERSION=3.2.5 | |
| NODE_VERSION=22.3.0 | |
| POSTGRES_VERSION=13 | |
| - path: /tmp/git_config.conf | |
| content: | | |
| GIT_USER_NAME="Your Name" | |
| GIT_USER_EMAIL="your.email@example.com" | |
| GIT_SIGNING_KEY="" | |
| GIT_SIGN_COMMITS=true | |
| GIT_AUTO_SETUP_REMOTE=true | |
| GIT_PULL_REBASE=true | |
| - path: /tmp/gitconfig.template | |
| content: | | |
| [user] | |
| name = {{GIT_USER_NAME}} | |
| email = {{GIT_USER_EMAIL}} | |
| {{GIT_SIGNING_KEY_LINE}} | |
| [commit] | |
| gpgsign = {{GIT_SIGN_COMMITS}} | |
| [push] | |
| autoSetupRemote = {{GIT_AUTO_SETUP_REMOTE}} | |
| [pull] | |
| rebase = {{GIT_PULL_REBASE}} | |
| - path: /home/ubuntu/setup.sh | |
| permissions: '0755' | |
| content: | | |
| #!/bin/bash | |
| set -e | |
| # Load versions | |
| source /tmp/versions.conf | |
| echo "Installing rbenv and ruby-build..." | |
| git clone https://github.com/rbenv/rbenv.git ~/.rbenv | |
| cd ~/.rbenv && src/configure && make -C src | |
| git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build | |
| echo "Installing Rust..." | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| source ~/.cargo/env | |
| echo "Installing nodenv and node-build..." | |
| git clone https://github.com/nodenv/nodenv.git ~/.nodenv | |
| cd ~/.nodenv && src/configure && make -C src | |
| git clone https://github.com/nodenv/node-build.git ~/.nodenv/plugins/node-build | |
| echo "Installing fzf..." | |
| git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf | |
| ~/.fzf/install --all --no-bash --no-fish | |
| echo "Installing Oh My Zsh..." | |
| sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended | |
| echo "Configuring Git..." | |
| source /tmp/git_config.conf | |
| # Create gitconfig from template | |
| cp /tmp/gitconfig.template ~/.gitconfig | |
| sed -i "s/{{GIT_USER_NAME}}/$GIT_USER_NAME/" ~/.gitconfig | |
| sed -i "s/{{GIT_USER_EMAIL}}/$GIT_USER_EMAIL/" ~/.gitconfig | |
| sed -i "s/{{GIT_SIGN_COMMITS}}/$GIT_SIGN_COMMITS/" ~/.gitconfig | |
| sed -i "s/{{GIT_AUTO_SETUP_REMOTE}}/$GIT_AUTO_SETUP_REMOTE/" ~/.gitconfig | |
| sed -i "s/{{GIT_PULL_REBASE}}/$GIT_PULL_REBASE/" ~/.gitconfig | |
| # Add signing key line if provided | |
| if [ -n "$GIT_SIGNING_KEY" ]; then | |
| sed -i "s|{{GIT_SIGNING_KEY_LINE}}| signingkey = $GIT_SIGNING_KEY|" ~/.gitconfig | |
| else | |
| sed -i "/{{GIT_SIGNING_KEY_LINE}}/d" ~/.gitconfig | |
| fi | |
| echo "Configuring zshrc..." | |
| # Enable Oh My Zsh plugins | |
| sed -i 's/plugins=(git)/plugins=(git bundler ruby rails rake postgres)/' ~/.zshrc | |
| echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc | |
| echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc | |
| echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.zshrc | |
| echo 'eval "$(nodenv init - zsh)"' >> ~/.zshrc | |
| echo '[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh' >> ~/.zshrc | |
| # Add PostgreSQL environment variables | |
| echo '' >> ~/.zshrc | |
| echo '# PostgreSQL environment variables' >> ~/.zshrc | |
| echo 'export PGHOST=localhost' >> ~/.zshrc | |
| echo 'export PGPORT=5432' >> ~/.zshrc | |
| echo 'export PGUSER=ubuntu' >> ~/.zshrc | |
| echo 'export PGPASSWORD=ubuntu' >> ~/.zshrc | |
| # Add vi mode and GPG TTY | |
| echo '' >> ~/.zshrc | |
| echo '# Vi mode' >> ~/.zshrc | |
| echo 'set -o vi' >> ~/.zshrc | |
| echo '' >> ~/.zshrc | |
| echo '# GPG TTY' >> ~/.zshrc | |
| echo 'export GPG_TTY=$(tty)' >> ~/.zshrc | |
| echo "Installing Ruby ${RUBY_VERSION} with YJIT..." | |
| export PATH="$HOME/.rbenv/bin:$PATH" | |
| eval "$(rbenv init - bash)" | |
| source ~/.cargo/env | |
| RUBY_CONFIGURE_OPTS="--enable-yjit" rbenv install $RUBY_VERSION | |
| rbenv global $RUBY_VERSION | |
| echo "Installing Node ${NODE_VERSION}..." | |
| export PATH="$HOME/.nodenv/bin:$PATH" | |
| eval "$(nodenv init - bash)" | |
| nodenv install $NODE_VERSION | |
| nodenv global $NODE_VERSION | |
| echo "Ruby: $RUBY_VERSION" > ~/installed_versions.txt | |
| echo "Node: $NODE_VERSION" >> ~/installed_versions.txt | |
| echo "PostgreSQL: $POSTGRES_VERSION" >> ~/installed_versions.txt | |
| echo "Setup complete!" | |
| package_update: true | |
| package_upgrade: true | |
| packages: | |
| - build-essential | |
| - git | |
| - curl | |
| - wget | |
| - zsh | |
| - libssl-dev | |
| - libreadline-dev | |
| - zlib1g-dev | |
| - autoconf | |
| - bison | |
| - libyaml-dev | |
| - libncurses-dev | |
| - libffi-dev | |
| - libgdbm-dev | |
| - gpg | |
| - unzip | |
| - software-properties-common | |
| - apt-transport-https | |
| - ca-certificates | |
| runcmd: | |
| # Exit on any error | |
| - set -e | |
| # Install PostgreSQL (specific version from config) | |
| - bash -c 'source /tmp/versions.conf && curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /usr/share/keyrings/postgresql-keyring.gpg' | |
| - echo "deb [signed-by=/usr/share/keyrings/postgresql-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list | |
| - apt-get update | |
| - bash -c 'source /tmp/versions.conf && DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql-${POSTGRES_VERSION} postgresql-contrib-${POSTGRES_VERSION} libpq-dev' | |
| # Configure PostgreSQL | |
| - systemctl enable postgresql | |
| - systemctl start postgresql | |
| # Wait for PostgreSQL to be ready | |
| - sleep 10 | |
| - until pg_isready -h localhost; do sleep 2; done | |
| # Create user | |
| - su - postgres -c "psql -c \"CREATE USER ubuntu WITH SUPERUSER PASSWORD 'ubuntu';\"" | |
| # Change default shell to zsh | |
| - chsh -s /usr/bin/zsh ubuntu | |
| # Ensure ubuntu owns their home directory | |
| - chown -R ubuntu:ubuntu /home/ubuntu | |
| # Create log file with proper permissions | |
| - touch /home/ubuntu/setup.log | |
| - chown ubuntu:ubuntu /home/ubuntu/setup.log | |
| - chmod 644 /home/ubuntu/setup.log | |
| # Run user setup script in background | |
| - su - ubuntu -c 'nohup /home/ubuntu/setup.sh > /home/ubuntu/setup.log 2>&1 &' | |
| final_message: | | |
| Rails development VM setup started! | |
| PostgreSQL is configured and running. | |
| Ruby, Node.js, and other tools are installing in the background. | |
| To check installation progress: | |
| multipass shell rails-dev | |
| tail -f ~/setup.log | |
| Once complete, you'll have: | |
| - Ruby (via rbenv) | |
| - Node.js (via nodenv) | |
| - PostgreSQL | |
| - Git, Zsh, Oh My Zsh, GPG, fzf | |
| You can then install Rails/Bundler as needed: | |
| gem install bundler rails | |
| NEXT STEPS: | |
| 1. Wait for setup to complete (check ~/setup.log) | |
| 2. Mount your GPG directory: | |
| multipass mount ~/.gnupg rails-dev:/home/ubuntu/.gnupg | |
| 3. Shell in (SSH agent forwarding is automatic): | |
| multipass shell rails-dev | |
| PostgreSQL credentials: | |
| - User: ubuntu | |
| - Password: ubuntu | |
| Create databases as needed with Rails or psql. | |
| Happy coding! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment