Skip to content

Instantly share code, notes, and snippets.

@delano
Last active September 23, 2024 19:34
Show Gist options
  • Select an option

  • Save delano/b11c3252db30274e74d390b311064500 to your computer and use it in GitHub Desktop.

Select an option

Save delano/b11c3252db30274e74d390b311064500 to your computer and use it in GitHub Desktop.

Revisions

  1. delano revised this gist Sep 23, 2024. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,7 @@
    # Guide to Running a Single Instance of OnetimeSecret on Ubuntu/Debian (Port 3000)

    **[Version 0.17.3](https://github.com/onetimesecret/onetimesecret/tree/v0.17.3)**

    This guide will walk you through the steps to set up and run a single instance of OnetimeSecret using Podman on an Ubuntu/Debian system. We will also install Redis, which is a required dependency for OnetimeSecret. The OnetimeSecret instance will be accessible on port **3000**.

    ## Prerequisites
  2. delano created this gist Sep 23, 2024.
    210 changes: 210 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,210 @@
    # Guide to Running a Single Instance of OnetimeSecret on Ubuntu/Debian (Port 3000)

    This guide will walk you through the steps to set up and run a single instance of OnetimeSecret using Podman on an Ubuntu/Debian system. We will also install Redis, which is a required dependency for OnetimeSecret. The OnetimeSecret instance will be accessible on port **3000**.

    ## Prerequisites

    1. **Ubuntu/Debian server**: Ensure you have a working Ubuntu/Debian server with `sudo` privileges.
    2. **Podman**: Podman is required to run the OnetimeSecret container.
    3. **Redis**: OnetimeSecret requires Redis to function.

    ---

    ### Step 1: Install Podman

    First, let's install Podman on your system.

    ```bash
    sudo apt update
    sudo apt install -y podman
    ```

    Verify that Podman is installed correctly by running:

    ```bash
    podman --version
    ```

    ---

    ### Step 2: Install Redis

    OnetimeSecret requires Redis to store secrets. Install Redis using the following commands:

    ```bash
    sudo apt update
    sudo apt install -y redis-server
    ```

    Start and enable Redis to run on boot:

    ```bash
    sudo systemctl start redis-server
    sudo systemctl enable redis-server
    ```

    Verify that Redis is running:

    ```bash
    sudo systemctl status redis-server
    ```

    ---

    ### Step 3: Prepare OnetimeSecret Configuration Files

    We will now create the necessary directories and configuration files for OnetimeSecret.

    1. **Create the base directory for OnetimeSecret**:

    ```bash
    sudo mkdir -p /opt/onetimesecret/config
    ```

    2. **Create the `.env` file** with the required environment variables. This file will store the configuration for your OnetimeSecret instance. Use the following command to create the file:

    ```bash
    sudo vi /opt/onetimesecret/config/.env
    ```

    Add the following content to the `.env` file (replace `CHANGEME` with your desired values):

    ```bash
    OTS_SECRET_KEY_BASE=CHANGEME
    OTS_REDIS_URL=redis://localhost:6379
    OTS_SITE_URL=http://localhost:3000
    ```

    Save and exit the file (`Ctrl + X`, then `Y`, and `Enter`).

    3. **Create the `config` file** for OnetimeSecret:

    Copy the etc/config.example.yaml file to `/opt/onetimesecret/config/config`

    ```bash
    sudo vi /opt/onetimesecret/config/config
    ```

    Update the following settings:

    ```yaml
    :site:
    :url: http://localhost:3000
    :secret: CHANGEME
    :redis:
    :url: redis://localhost:6379
    ```
    Save and exit the file.
    ---
    ### Step 4: Run the OnetimeSecret Container
    We will now run a single instance of OnetimeSecret using Podman on port **3000**.
    1. **Set the necessary variables**:
    ```bash
    BASE_DIR="/opt/onetimesecret"
    IMAGE="ghcr.io/onetimesecret/onetimesecret:latest"
    PORT=3000
    ENV_FILE=$BASE_DIR/.env-$PORT
    NAME=onetime-$PORT
    ```

    2. **Create the environment file** by copying the `.env` file and modifying it for port 3000:

    ```bash
    sudo cp --no-clobber --preserve=mode,timestamps /opt/onetimesecret/config/.env $ENV_FILE
    sudo sed -i "s/CHANGEME/$PORT/" $ENV_FILE
    ```

    3. **Run the OnetimeSecret container** on port 3000:

    ```bash
    podman run -d --name $NAME \
    --network host \
    --env-file=$ENV_FILE \
    -v $BASE_DIR/config/config.yaml:/app/etc/config:ro \
    $IMAGE \
    bundle exec thin -R config.ru -p $PORT start
    ```

    4. **Generate a systemd service file** for the container:

    ```bash
    podman generate systemd --name $NAME --files --new
    ```

    5. **Move the generated service file** to the systemd directory:

    ```bash
    sudo mv container-$NAME.service /etc/systemd/system/
    ```

    6. **Reload the systemd daemon** to recognize the new service:

    ```bash
    sudo systemctl daemon-reload
    ```

    7. **Enable and start the OnetimeSecret service**:

    ```bash
    sudo systemctl enable --now container-$NAME.service
    ```

    8. **Verify that the service is running**:

    ```bash
    sudo systemctl status container-onetime-3000.service
    ```

    ---

    ### Step 5: Access OnetimeSecret

    You can now access your OnetimeSecret instance by navigating to the following URL in your browser:

    ```
    http://localhost:3000
    ```

    If you are running this on a remote server, replace `localhost` with your server's IP address.

    ---

    ### Step 6: Manage the OnetimeSecret Service

    You can manage the OnetimeSecret service using the following commands:

    - **Start the service**:

    ```bash
    sudo systemctl start container-onetime-3000.service
    ```

    - **Stop the service**:

    ```bash
    sudo systemctl stop container-onetime-3000.service
    ```

    - **Restart the service**:

    ```bash
    sudo systemctl restart container-onetime-3000.service
    ```

    - **Check the status of the service**:

    ```bash
    sudo systemctl status container-onetime-3000.service
    ```

    ---

    ### Conclusion

    You have successfully set up and run a single instance of OnetimeSecret on your Ubuntu/Debian server using Podman. You can now use this instance to securely share secrets via port **3000**.
    227 changes: 227 additions & 0 deletions config.example.yaml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,227 @@
    ---
    :site:
    :host: <%= ENV['HOST'] || 'localhost:3000' %>
    :domains:
    :enabled: <%= ENV['DOMAINS_ENABLED'] || false %>
    # The default domain used for link URLs. When not set or empty,
    # site.host is used.
    :default: <%= ENV['DEFAULT_DOMAIN'] || nil %>
    # The cluster type determines how the application will support
    # multiple domains. The default is nil which means that the
    # application itself is responsible for handling multiple domains.
    :cluster:
    :type: <%= ENV['CLUSTER_TYPE'] || nil %>
    :api_key: <%= ENV['APPROXIMATED_API_KEY'] || nil %>
    :cluster_ip: <%= ENV['APPROXIMATED_PROXY_CLUSTER_IP'] || '<CLUSTER_IP>' %>
    :cluster_name: <%= ENV['APPROXIMATED_PROXY_CLUSTER_NAME'] || '<CLUSTER_NAME>' %>
    :vhost_target: <%= ENV['APPROXIMATED_PROXY_VHOST_TARGET'] || '<VHOST_TARGET>' %>
    # Turns https/http on or off when generating links
    :ssl: <%= ENV['SSL'] == 'true' %>
    # IMPORTANT: After setting the secret, it should not be changed.
    # Ensure to create and store a backup in a secure offsite
    # location. Changing the secret can lead to unforeseen issues.
    :secret: <%= ENV['SECRET'] || 'CHANGEME' %>
    # Registration and Authentication settings
    :authentication:
    # Can be disabled altogether, including API authentication.
    :enabled: <%= ENV['AUTH_ENABLED'] || true %>
    # Allow users to create accounts. This can be disabled if you plan
    # to create accounts manually or enable during setup when accounts
    # can be created and then disabled to prevent any new users from
    # creating accounts.
    :signup: <%= ENV['AUTH_SIGNUP'] || true %>
    # Generally if you allow registration, you allow signin. But there
    # are circumstances where it's helpful to turn off authentication
    # temporarily.
    :signin: <%= ENV['AUTH_SIGNIN'] || true %>
    # By default, new accounts need to verify their email address before
    # they can sign in. This is a security measure to prevent spamming
    # and abuse of the system. If you're running a private instance or
    # an instance for your team or company, you can disable this feature
    # to make it easier for users to sign in.
    :autoverify: <%= ENV['AUTH_AUTOVERIFY'] || false %>
    :authenticity:
    :type: <%= ENV['AUTHENTICITY_TYPE'] || 'altcha' %>
    :secret_key: <%= ENV['AUTHENTICITY_SECRET_KEY'] || '<REPLACE_WITH_STRONG_HMAC_KEY>' %>
    :plans:
    :enabled: <%= ENV['PLANS_ENABLED'] || false %>
    :stripe_key: <%= ENV['STRIPE_KEY'] || nil %>
    :support:
    :host: <%= ENV['SUPPORT_HOST'] || nil %>
    :redis:
    :uri: <%= ENV['REDIS_URL'] || 'redis://CHANGEME@127.0.0.1:6379/0' %>
    :colonels:
    # Email addresses listed below will be granted automatic
    # administrative privileges upon account creation. These
    # accounts will have full control over the system.
    - <%= ENV['COLONEL'] || 'CHANGEME@example.com' %>
    :emailer:
    :mode: <%= ENV['EMAILER_MODE'] || :smtp %>
    :from: <%= ENV['FROM'] || 'CHANGEME@example.com' %>
    :fromname: <%= ENV['FROMNAME'] || 'Jan' %>
    :host: <%= ENV['SMTP_HOST'] || 'localhost' %>
    :port: <%= ENV['SMTP_PORT'] || 587 %>
    :user: <%= ENV['SMTP_USERNAME'] || 'CHANGEME' %>
    :pass: <%= ENV['SMTP_PASSWORD'] || 'CHANGEME' %>
    :pass: <%= ENV['SMTP_PASSWORD'] || 'CHANGEME' %>
    :auth: <%= ENV['SMTP_AUTH'] || 'login' %>
    :tls: <%= ENV['SMTP_TLS'] || true %>
    :incoming:
    :enabled: false
    :email: CHANGEME@example.com
    :passphrase: abacus
    :mail:
    :truemail:
    # Available validation types: :regex, :mx, :mx_blacklist, :smtp
    :default_validation_type: :regex
    # Required for :smtp validation
    :verifier_email: <%= ENV['VERIFIER_EMAIL'] || 'CHANGEME@example.com' %>
    #:verifier_domain: <%= ENV['VERIFIER_DOMAIN'] || 'example.com' %>
    #:connection_timeout: 2
    #:response_timeout: 2
    #:connection_attempts: 3
    #:validation_type_for:
    # 'example.com': :regex
    #
    # Truemail will only validate email addresses that match the
    # domains listed in :allowed_domains. If the domain is not
    # listed, the email address will always be considered invalid.
    :allowed_domains_only: false
    #
    # Email addresses in this list will always be valid.
    #:allowed_emails: []
    #
    # Email addresses in this list will always be invalid.
    #:blocked_emails: []
    #
    # Addresses with these domains will always be valid
    #:allowed_domains: []
    #
    # Addresses with these domains will always be invalid
    #:blocked_domains: []
    #
    # Exclude these IP addresses from the MX lookup process.
    #:blocked_mx_ip_addresses: []
    #
    # Name servers to use for MX et al record lookup.
    # Default is CloudFlare, Google, Oracle/OpenDNS servers.
    :dns:
    - 1.1.1.1
    - 8.8.4.4
    - 208.67.220.220
    #:smtp_port: 25
    #
    # End smtp validation after the first invalid response rather than
    # retrying, followed by trying the next server. Can reduce the time
    # time to validate an email address, but may not catch all issues.
    :smtp_fail_fast: false
    #
    # Parse the content of the SMTP error message to determine if the
    # email address is valid. This can be useful for some SMTP servers
    # that don't return exact answers.
    :smtp_safe_check: true
    #
    # Whether to disable the RFC MX lookup flow. When true, only DNS
    # validation will be performed on MX and Null MX records.
    :not_rfc_mx_lookup_flow: false
    #
    # Override default regular expression pattern for email addresses
    # and/or the content in SMTP error messages.
    #:email_pattern: /regex_pattern/
    #:smtp_error_body_pattern: /regex_pattern/
    #
    # Log to the console, a file, or both. The ruby process must have
    # write access to the log file. The log file will be created if it
    # does not exist. Log file rotation is not handled by the app.
    :logger:
    # One of: :error (default), :unrecognized_error,
    # :recognized_error, :all.
    tracking_event: :error
    stdout: true
    # log_absolute_path: '/home/app/log/truemail.log'
    :locales:
    # A list of ISO language codes (e.g., 'en' for English, 'es'
    # for Spanish, etc.). There is a corresponding file in etc/locales
    # with the same name containing the translated text. If it's not
    # selected automatically, users are able to select their preferred
    # language by using the links on the translations page.
    #
    # NOTE: The default locale is the first item.
    - en
    - ar
    - bg
    - ca_ES
    - cn
    - cs
    - da_DK
    - de
    - el_GR
    - en
    - es
    - fr
    - fr_FR
    - he
    - hu
    - it_IT
    - nl
    - pl
    - pt_BR
    - pt_PT
    - ru
    - sl_SI
    - sv_SE
    - tr
    - uk
    - vi
    :services:
    :sentry:
    :dsn: <%= ENV['SENTRY_DSN'] || 'CHANGEME' %>
    :enabled: <%= !ENV['SENTRY_DSN'].nil? %>
    :limits:
    # This section defines rate limits for various events per user
    # per a rolling 20 minute period. Each key is an event name
    # and the value is the max count allowed. Changes require
    # restart of the app.
    :create_secret: 1000
    :create_account: 10
    :update_account: 10
    :email_recipient: 50
    :send_feedback: 10
    :authenticate_session: 5
    :homepage: 1000
    :dashboard: 1000
    :failed_passphrase: 5
    :show_metadata: 1000
    :show_secret: 1000
    :burn_secret: 1000
    :destroy_account: 2
    :forgot_password_request: 2
    :forgot_password_reset: 3
    :generate_apikey: 10
    :add_domain: 30
    :remove_domain: 30
    :list_domains: 100
    :get_domain: 100
    :verify_domain: 25
    :development:
    # Enabling development mode here directs the application to expect
    # a vite server to be running on port 5173 and will attempt to
    # connect to that server for each request. This is useful for
    # development when you want to use a local instance of the frontend
    # and not have to rebuild it every time you make changes.
    #
    # $ pnpm run dev
    # VITE v5.3.4 ready in 38 ms
    #
    # ➜ Local: http://localhost:5173/dist/
    # ➜ Network: use --host to expose
    # ➜ press h + enter to show help
    #
    # Disabling development mode will cause the application to use the
    # pre-built JS/CSS assets in the "public/web/dist" directory. This
    # is useful for production deployments but also for any deployment
    # where you're not actively working on the frontend JS/CSS etc.
    # Setting RACK_ENV=production disables development mode automatically.
    :enabled: <%= ['development', 'dev'].include?(ENV['RACK_ENV']) %>
    :debug: <%= ['true', '1', 'yes'].include?(ENV['ONETIME_DEBUG']) %>
    :frontend_host: <%= ENV['FRONTEND_HOST'] || 'http://localhost:5173' %>