diff --git a/README.md b/README.md
index 959135b7..eeda3254 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,11 @@ There are 3 primary ways to use the Maybe app:
## Local Development Setup
+**If you are trying to _self-host_ the Maybe app, stop here. You
+should [read this guide to get started](docs/hosting/docker.md).**
+
+The instructions below are for developers to get started with contributing to the app.
+
### Requirements
- Ruby 3.3.1
diff --git a/app/controllers/settings/hostings_controller.rb b/app/controllers/settings/hostings_controller.rb
index 36b9a0ee..89a42946 100644
--- a/app/controllers/settings/hostings_controller.rb
+++ b/app/controllers/settings/hostings_controller.rb
@@ -47,7 +47,7 @@ class Settings::HostingsController < SettingsController
end
end
- if hosting_params[:upgrades_mode] != "manual" && hosting_params[:render_deploy_hook].blank?
+ if hosting_params[:upgrades_mode] == "auto" && hosting_params[:render_deploy_hook].blank?
@errors.add(:render_deploy_hook, t("settings.hostings.update.render_deploy_hook_error"))
end
diff --git a/app/views/settings/hostings/show.html.erb b/app/views/settings/hostings/show.html.erb
index 2e8dd0ae..37c1f3f6 100644
--- a/app/views/settings/hostings/show.html.erb
+++ b/app/views/settings/hostings/show.html.erb
@@ -5,47 +5,52 @@
<%= t(".page_title") %>
<%= settings_section title: t(".general_settings_title") do %>
<%= form_with model: Setting.new, url: settings_hosting_path, method: :patch, local: true, html: { class: "space-y-6", data: { controller: "auto-submit-form", "auto-submit-form-trigger-event-value" => "blur" } } do |form| %>
-
-
<%= t(".upgrades.title") %>
-
<%= t(".upgrades.description") %>
-
-
- <%= form.radio_button :upgrades_mode, "manual", checked: Setting.upgrades_mode == "manual", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_manual, t(".upgrades.manual.title"), class: "text-gray-900 text-sm" do %>
-
<%= t(".upgrades.manual.title") %>
-
-
+
+ <% if ENV["HOSTING_PLATFORM"] == "render" %>
+
+
<%= t(".upgrades.title") %>
+
<%= t(".upgrades.description") %>
+
+
+ <%= form.radio_button :upgrades_mode, "manual", checked: Setting.upgrades_mode == "manual", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_manual, t(".upgrades.manual.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.manual.title") %>
+
+
<%= t(".upgrades.manual.description") %>
- <% end %>
-
-
- <%= form.radio_button :upgrades_mode, "release", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "release", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_release, t(".upgrades.latest_release.title"), class: "text-gray-900 text-sm" do %>
- <%= t(".upgrades.latest_release.title") %>
-
-
+ <% end %>
+
+
+ <%= form.radio_button :upgrades_mode, "release", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "release", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_release, t(".upgrades.latest_release.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.latest_release.title") %>
+
+
<%= t(".upgrades.latest_release.description") %>
- <% end %>
-
-
- <%= form.radio_button :upgrades_mode, "commit", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "commit", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
- <%= form.label :upgrades_mode_commit, t(".upgrades.latest_commit.title"), class: "text-gray-900 text-sm" do %>
- <%= t(".upgrades.latest_commit.title") %>
-
-
+ <% end %>
+
+
+ <%= form.radio_button :upgrades_mode, "commit", checked: Setting.upgrades_mode == "auto" && Setting.upgrades_target == "commit", data: { "auto-submit-form-target" => "auto", "autosubmit-trigger-event": "input" } %>
+ <%= form.label :upgrades_mode_commit, t(".upgrades.latest_commit.title"), class: "text-gray-900 text-sm" do %>
+ <%= t(".upgrades.latest_commit.title") %>
+
+
<%= t(".upgrades.latest_commit.description") %>
- <% end %>
+ <% end %>
+
-
-
-
<%= t(".provider_settings.title") %>
-
<%= t(".render_deploy_hook_description") %>
- <%= form.url_field :render_deploy_hook, label: t(".render_deploy_hook_label"), placeholder: t(".render_deploy_hook_placeholder"), value: Setting.render_deploy_hook, data: { "auto-submit-form-target" => "auto" } %>
-
+
+
+
<%= t(".provider_settings.title") %>
+
<%= t(".render_deploy_hook_description") %>
+ <%= form.url_field :render_deploy_hook, label: t(".render_deploy_hook_label"), placeholder: t(".render_deploy_hook_placeholder"), value: Setting.render_deploy_hook, data: { "auto-submit-form-target" => "auto" } %>
+
+ <% end %>
+
<%= t(".smtp_settings.title") %>
<%= t(".smtp_settings.description") %>
@@ -69,13 +74,14 @@
- <%= link_to t(".smtp_settings.send_test_email_button"), send_test_email_settings_hosting_path, data: { turbo_method: :post }, class:"bg-gray-50 text-gray-900 text-sm font-medium rounded-lg px-3 py-2" %>
+ <%= link_to t(".smtp_settings.send_test_email_button"), send_test_email_settings_hosting_path, data: { turbo_method: :post }, class: "bg-gray-50 text-gray-900 text-sm font-medium rounded-lg px-3 py-2" %>
<% end %>
<% end %>
+
<%= previous_setting("Billing", settings_billing_path) %>
<%= next_setting("Accounts", accounts_path) %>
diff --git a/docker-compose.example.yml b/docker-compose.example.yml
index f7f1a3c1..cbd5232a 100644
--- a/docker-compose.example.yml
+++ b/docker-compose.example.yml
@@ -1,21 +1,55 @@
+# ===========================================================================
+# Example Docker Compose file
+# ===========================================================================
+#
+# Purpose:
+# --------
+#
+# This file is an example Docker Compose configuration for self hosting
+# Maybe on your local machine or on a cloud VPS.
+#
+# The configuration below is a "standard" setup, but may require modification
+# for your specific environment.
+#
+# Setup:
+# ------
+#
+# To run this, you should read the setup guide:
+#
+# https://github.com/maybe-finance/maybe/blob/main/docs/hosting/docker.md
+#
+# Troubleshooting:
+# ----------------
+#
+# If you run into problems, you should open a Discussion here:
+#
+# https://github.com/maybe-finance/maybe/discussions/categories/general
+#
+
services:
app:
image: ghcr.io/maybe-finance/maybe:latest
+
volumes:
- ./storage:/rails/storage
+
ports:
- - 127.0.0.1:3000:3000
+ - 3000:3000
+
restart: unless-stopped
- env_file:
- - .env
+
environment:
- SELF_HOSTING_ENABLED: true
- DB_HOST: postgres
- RAILS_FORCE_SSL: false
- RAILS_ASSUME_SSL: false
- POSTGRES_USER: postgres
+ SELF_HOSTING_ENABLED: "true"
+ RAILS_FORCE_SSL: "false"
+ RAILS_ASSUME_SSL: "false"
GOOD_JOB_EXECUTION_MODE: async
+ SECRET_KEY_BASE: ${SECRET_KEY_BASE:?}
+ DB_HOST: postgres
+ POSTGRES_DB: ${POSTGRES_DB:-maybe_production}
+ POSTGRES_USER: ${POSTGRES_USER:-maybe_user}
+ POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?}
+
depends_on:
postgres:
condition: service_healthy
@@ -26,11 +60,11 @@ services:
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER: ${POSTGRES_USER:-postgres}
+ POSTGRES_USER: ${POSTGRES_USER:-maybe_user}
POSTGRES_DB: ${POSTGRES_DB:-maybe_production}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?}
healthcheck:
- test: [ "CMD-SHELL", "pg_isready -U $$POSTGRES_USER" ]
+ test: [ "CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" ]
interval: 5s
timeout: 5s
retries: 5
diff --git a/docs/hosting/docker.md b/docs/hosting/docker.md
index b16b4ffa..425a4c75 100644
--- a/docs/hosting/docker.md
+++ b/docs/hosting/docker.md
@@ -1,102 +1,177 @@
# Self Hosting Maybe with Docker
-## Quick Start
+This guide will help you setup, update, and maintain your self-hosted Maybe application with Docker Compose. Docker Compose is the most popular and recommended way to self-host the Maybe app.
-_The below quickstart assumes you're running on Mac or Linux. Windows will
-be different._
+If you want a _less
+technical_ way to host the Maybe app, you can [host on Render](/docs/hosting/one-click-deploy.md) as an
+_**alternative** to Docker Compose_.
-Make sure [Docker is installed](https://docs.docker.com/engine/install/) and
-setup your local environment:
+## Setup Guide
+
+Follow the guide below to get your app running.
+
+### Step 1: Install Docker
+
+Complete the following steps:
+
+1. Install Docker Engine by following [the official guide](https://docs.docker.com/engine/install/)
+2. Start the Docker service on your machine
+3. Verify that Docker is installed correctly and is running by opening up a terminal and running the following command:
+
+```bash
+# If Docker is setup correctly, this command will succeed
+docker run hello-world
+```
+
+### Step 2: Configure your Docker Compose file and environnment
+
+#### Create a directory for your app to run
+
+Open your terminal and create a directory where your app will run. Below is an example command with a recommended directory:
```bash
# Create a directory on your computer for Docker files
mkdir -p ~/docker-apps/maybe
+
+# Once created, navigate your current working directory to the new folder
cd ~/docker-apps/maybe
-
-# Download the sample docker-compose.yml file from the Maybe Github repository
-curl -o docker-compose.yml https://raw.githubusercontent.com/maybe-finance/maybe/main/docker-compose.example.yml
-
-# Create an .env file (make sure to fill in empty variables manually)
-cat << EOF > .env
-# Use "openssl rand -hex 64" to generate this
-SECRET_KEY_BASE=
-
-# Can be any value, set to what you'd like
-POSTGRES_PASSWORD=
-EOF
```
-Make sure to generate your `SECRET_KEY_BASE` value and save the `.env` file.
-Then you're ready to run the app, which will be available at
-`http://localhost:3000` in your browser:
+#### Copy our sample Docker Compose file
+
+Make sure you are in the directory you just created and run the following command:
```bash
-docker-compose up -d
+# Download the sample docker-compose.yml file from the Maybe Github repository
+curl -o compose.yml https://raw.githubusercontent.com/maybe-finance/maybe/main/docker-compose.example.yml
```
-Lastly, go to `http://localhost:3000` in your browser, **create a new
-account**, and you're ready to start tracking your finances!
+This command will do the following:
-## Detailed Setup Guide
+1. Fetch the sample docker compose file from our public Github repository
+2. Creates a file in your current directory called `compose.yml` with the contents of the example file
-### Prerequisites
+At this point, the only file in your current working directory should be `compose.yml`.
-- Install Docker Engine by
- following [the official guide](https://docs.docker.com/engine/install/)
-- Start the Docker service on your machine
+#### Create your environment file
-### App Setup
+In order to configure the app, you will need to create a file called `.env`, which is where Docker will read environment variables from.
-1. Create a new directory on your machine (we suggest something like
- `$HOME/docker-apps/maybe`)
-2. Create a `docker-compose.yml` file (we suggest
- using [our example](/docker-compose.example.yml)
- if
- you're new to self-hosting and Docker)
-3. Create a `.env` file and add the required variables. Currently,
- `SECRET_KEY_BASE` is the only required variable, but you can take a look
- at our [.env.example](/.env.example) file to see all available options.
+To do this, run the following command:
-### Run app with Docker Compose
+```bash
+touch .env
+```
-1. Run `docker-compose up -d` to start the maybe app in detached mode.
-2. Access the Maybe app by navigating to http://localhost:3000 in your web
- browser.
+#### Generate the app secret key
-### Updating the App
+The app requires an environment variable called `SECRET_KEY_BASE` to run.
-The mechanism that updates your self-hosted Maybe app is the GHCR (Github
-Container Registry) Docker image that you see in the `docker-compose.yml` file:
+We will first need to generate this in the terminal. If you have `openssl` installed on your computer, you can generate it with the following command:
+
+```bash
+openssl rand -hex 64
+```
+
+_Alternatively_, you can generate a key without openssl or any external dependencies by pasting the following bash command in your terminal and running it:
+
+```bash
+head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n' && echo
+```
+
+Once you have generated a key, save it and move on to the next step.
+
+#### Fill in your environment file
+
+Open the file named `.env` that we created in a prior step using your favorite text editor.
+
+Fill in this file with the following variables:
+
+```txt
+SECRET_KEY_BASE="replacemewiththegeneratedstringfromthepriorstep"
+POSTGRES_PASSWORD="replacemewithyourdesireddatabasepassword"
+```
+
+### Step 3: Test your app
+
+You are now ready to run the app. Start with the following command to make sure everything is working:
+
+```bash
+docker compose up
+```
+
+This will pull our official Docker image and start the app. You will see logs in your terminal.
+
+Open your browser, and navigate to `http://localhost:3000`.
+
+If everything is working, you will see the Maybe login screen.
+
+### Step 4: Create your account
+
+The first time you run the app, you will need to register a new account by hitting "register" on the login page.
+
+1. Enter your email
+2. Enter a password
+
+### Step 5: Run the app in the background
+
+Most self-hosting users will want the Maybe app to run in the background on their computer so they can access it at all times. To do this, hit `Ctrl+C` to stop the running process, and then run the following command:
+
+```bash
+docker compose up -d
+```
+
+The `-d` flag will run Docker Compose in "detached" mode. To verify it is running, you can run the following command:
+
+```
+docker compose ls
+```
+
+### Step 6: Enjoy!
+
+Your app is now set up. You can visit it at `http://localhost:3000` in your browser.
+
+If you find bugs or have a feature request, be sure to read through our [contributing guide here](https://github.com/maybe-finance/maybe/wiki/How-to-Contribute-Effectively-to-this-Project).
+
+## How to update your app
+
+The mechanism that updates your self-hosted Maybe app is the GHCR (Github Container Registry) Docker image that you see in the `docker-compose.yml` file:
```yml
image: ghcr.io/maybe-finance/maybe:latest
```
-We recommend using one of the following images, but you can pin your app to
-whatever version you'd like (
-see [packages](https://github.com/maybe-finance/maybe/pkgs/container/maybe)):
+We recommend using one of the following images, but you can pin your app to whatever version you'd like (see [packages](https://github.com/maybe-finance/maybe/pkgs/container/maybe)):
- `ghcr.io/maybe-finance/maybe:latest` (latest commit)
- `ghcr.io/maybe-finance/maybe:stable` (latest release)
-By default, your app _will NOT_ automatically update. To update your
-self-hosted app, you must run the following commands:
+By default, your app _will
+NOT_ automatically update. To update your self-hosted app, run the following commands in your terminal:
```bash
-docker-compose pull # This pulls the "latest" published image from GHCR
-
-docker-compose up -d # Restarts the app
+cd ~/docker-apps/maybe # Navigate to whatever directory you configured the app in
+docker compose pull # This pulls the "latest" published image from GHCR
+docker compose build app # This rebuilds the app with updates
+docker compose up --no-deps -d app # This restarts the app using the newest version
```
-#### Changing the image
+## How to change which updates your app receives
-If you'd like to pin the app to a specific version or tag, all you need to do is
-edit the `docker-compose.yml` file:
+If you'd like to pin the app to a specific version or tag, all you need to do is edit the `docker-compose.yml` file:
```yml
image: ghcr.io/maybe-finance/maybe:stable
```
+After doing this, make sure and restart the app:
+
+```bash
+docker compose pull # This pulls the "latest" published image from GHCR
+docker compose build app # This rebuilds the app with updates
+docker compose up --no-deps -d app # This restarts the app using the newest version
+```
+
## Troubleshooting
This section will provide troubleshooting tips and solutions for common issues