Deploy the application

On a local computer:

Clone the repository

git clone git@github.com:UWM-Libraries/GeoDiscovery.git
cd GeoDiscovery

Ensure you’ve set up Git in your development environment and have set up your SSH key on GitHub.

Configure .env Files

Copy the example .env files:

```bash
cp .example.env.test .env.test
```

```bash
cp .example.env.development .env.development
```

After you copy the files, update them to include your database and solr connections

  • Solr port 8983
  • Geoblacklight port 3000

Bundle dependencies

The application’s RubyGem dependencies are listed in the project Gemfile.

Bundle the gems via this command:

bundle install

If the Gemfile has changed recently, you might need to run an additional command to get all the latest updates:

bundle update

Database initialization

You’ll need a local database for development and test modes. Both can just use sqlite.

bundle exec rake db:create
bundle exec rake db:migrate

Start the application

bundle exec rake uwm:server

You should now be able to interact with the application in the browser at http://localhost:3000

or via the command line by running rails console in the GeoDiscovery directory while the app is running.

It’s a good idea to run tests to make sure everything was installed and updated correctly.

You can now do feature development on your local machine to test out changes or new features.

Deploy to the liblamp-dev or liblamp:

  1. Create a SSL Key pair or check if you have existing ssh keys

     ls -al ~/.ssh
    

    If you get ...no such file or directory you likley have no SSH keys set up.

     ssh-keygen -t rsa -C "your@email.address"
    

    Save the keys in the default directory, likley ~/.ssh

  2. Deploy Public SSL Key to server to enable password-less login.

    Start the ssh-agent:

     eval "$(ssh-agent -s)"
    

    Adding SSH private keys into the SSH authentication agent:

     ssh-add ~/.ssh/id_rsa
    

    This makes Capistrano recognize your SSL key. If this isn’t run, you’ll get an error: “fatal: Could not read from remote repository.” More Info

     cat ~/.ssh/id_rsa.pub
    

    Add public key to /home/ad.uwm.edu//.ssh/authorized_keys as the geoblacklight user on the remote server

    You can use RSA style SSH keys or ed25519 style.

    To use ed25519 style, simply replace rsa with ed25519 in the steps above.

    We added some gems to the gemfile to allow this functionality:

    # ED SSH Key support
    gem "ed25519", ">=1.2", "< 2.0"
    gem "bcrypt_pbkdf", "~> 1.0", "< 2.0"
    
  3. Set up shared directory to add database and solr credentials on the server that is hosting the instance of software (First time only)

  4. Run capistrano command to deploy to directory.

Will likely break on first run for new servers and users. This is normal, read error logs and warnings to troubleshoot dependecy issues, etc.

Deploy to liblamp-dev:

bundle exec cap development deploy

Deploy to liblamp:

bundle exec cap production deploy

These commands will run Capistrano and deploy the application to development or production respectively.

If it’s sucessful, it will be saved in the current-release directory found at /var/www/rubyapps/uwm-geoblacklight/current/. The directory is actually a shortcut to /var/www/rubyapps/uwm-geoblacklight/releases/latest where latest is represented by a numerical version number according to it’s creation date, e.g. 20240612212046/

OpenGeoMetadata files stored in /tmp/opengeometadata are not moved over to the new release as part of the deploy process. .env.production should be modified to point GeoCombine’s OGM_PATH environment variable to /var/www/rubyapps/uwm-geoblacklight/shared/tmp/opengeometadata.

OGM_PATH=/var/www/rubyapps/uwm-geoblacklight/shared/tmp/opengeometadata

If you get the following error: ERROR linked file /var/www/rubyapps/uwm-geoblacklight/shared/config/blacklight.yml does not exit… There are three files in that dir that need to be copied over.

  1. “config/blacklight.yml”
  2. “config/database.yml”
  3. “config/master.key”

Configure Cron jobs with Whenever

Since schedule.rb, the file that Whenever uses to set up Cron jobs, is committed to version control, we might need to modify it depending on the environment you’re deploying to.

For example, I do not want the Cron job that pulls down metadata from OpenGeoMetadata to run on the development site while testing new functionality for GeoCombine. You can edit the schedule.rb file in the current release on LibLamp-Dev or LibLamp and then write the changes to the system’s crontab by running…

whenever --write-crontab

or for short,

whenever -w

The Readme file on the Whenever gem’s repository implies that Whenever --update-crontab is the command to use, but when I used Whenever -help, the appropriate command was the one used above. Not sure why there is this inconsistency. You can always double check the system’s crontab at /var/spool/cron/geoblacklight to make sure your changes are reflected.

Redis and Sidekiq

The GBL application enques jobs to Sidekiq from a Redis list, sidekiq is supposed to be monitoring redis for new jobs.

You can check if things are working with bundle exec sidekiqmon which should bring up an overview of sidekiq’s status. If that doesn’t work, it’s likley that either Sidekiq or Redis is not running.

You can see if the redis service is failing with systemctl --failed and check to see if it’s there. If it is showing failed, restart redis with sudo systemctl restart redis.

You can run sidekiq with bundle exec sidekiq but daemonizing it makes more sense:

Daemonizing sidekiq:

based on this blog

  • Create a new file for Sidekiq service:

    sudo nano /lib/systemd/system/sidekiq.service

  • Add the following content in the service file:

      #
      # This file tells systemd how to run Sidekiq as a 24/7 long-running daemon.
      #
      # Customize this file based on your bundler location, app directory, etc.
      #
      # If you are going to run this as a user service (or you are going to use capistrano-sidekiq)
      # Customize and copy this to ~/.config/systemd/user
      # Then run:
      #   - systemctl --user enable sidekiq
      #   - systemctl --user {start,stop,restart} sidekiq
      # Also you might want to run:
      #   - loginctl enable-linger username
      # So that the service is not killed when the user logs out.
      #
      # If you are going to run this as a system service
      # Customize and copy this into /usr/lib/systemd/system (CentOS) or /lib/systemd/system (Ubuntu).
      # Then run:
      #   - systemctl enable sidekiq
      #   - systemctl {start,stop,restart} sidekiq
      #
      # This file corresponds to a single Sidekiq process.  Add multiple copies
      # to run multiple processes (sidekiq-1, sidekiq-2, etc).
      #
      # Use `journalctl -u sidekiq -rn 100` to view the last 100 lines of log output.
      #
      [Unit]
      Description=sidekiq
      # start us only once the network and logging subsystems are available,
      # consider adding redis-server.service if Redis is local and systemd-managed.
      After=syslog.target network.target
        
      # See these pages for lots of options:
      #
      #   https://www.freedesktop.org/software/systemd/man/systemd.service.html
      #   https://www.freedesktop.org/software/systemd/man/systemd.exec.html
      #
      # THOSE PAGES ARE CRITICAL FOR ANY LINUX DEVOPS WORK; read them multiple
      # times! systemd is a critical tool for all developers to know and understand.
      #
      [Service]
      #
      #      !!!!  !!!!  !!!!
      #
      # As of v6.0.6, Sidekiq automatically supports systemd's `Type=notify` and watchdog service
      # monitoring. If you are using an earlier version of Sidekiq, change this to `Type=simple`
      # and remove the `WatchdogSec` line.
      #
      #      !!!!  !!!!  !!!!
      #
      Type=notify
      NotifyAccess=all
      # If your Sidekiq process locks up, systemd's watchdog will restart it within seconds.
      WatchdogSec=10
        
      WorkingDirectory=/var/www/rubyapps/uwm-geoblacklight/current
      # If you use rbenv:
      # ExecStart=/bin/bash -lc 'exec /home/deploy/.rbenv/shims/bundle exec sidekiq -e production'
      # If you use the system's ruby:
      # ExecStart=/usr/local/bin/bundle exec sidekiq -e production
      # If you use rvm in production without gemset and your ruby version is 2.6.5
      # ExecStart=/home/deploy/.rvm/gems/ruby-2.6.5/wrappers/bundle exec sidekiq -e production
      # If you use rvm in production with gemset and your ruby version is 2.6.5
      # ExecStart=/home/deploy/.rvm/gems/ruby-2.6.5@gemset-name/wrappers/bundle exec sidekiq -e production
      # If you use rvm in production with gemset and ruby version/gemset is specified in .ruby-version,
      # .ruby-gemsetor or .rvmrc file in the working directory
      ExecStart=/usr/local/rvm/bin/rvm in /var/www/rubyapps/uwm-geoblacklight/current do bundle exec sidekiq -e production
        
      # Use `systemctl kill -s TSTP sidekiq` to quiet the Sidekiq process
        
      # Uncomment this if you are going to use this as a system service
      # if using as a user service then leave commented out, or you will get an error trying to start the service
      # !!! Change this to your deploy user account if you are using this as a system service !!!
      # User=deploy
      # Group=deploy
      # UMask=0002
        
      # Greatly reduce Ruby memory fragmentation and heap usage
      # https://www.mikeperham.com/2018/04/25/taming-rails-memory-bloat/
      Environment=MALLOC_ARENA_MAX=2
        
      # if we crash, restart
      RestartSec=1
      Restart=always
        
      # output goes to /var/log/syslog (Ubuntu) or /var/log/messages (CentOS)
      StandardOutput=syslog
      StandardError=syslog
        
      # This will default to "bundler" if we don't specify it
      SyslogIdentifier=sidekiq
        
      [Install]
      WantedBy=multi-user.target
      # Uncomment this and remove the line above if you are going to use this as a user service
      # WantedBy=default.target
    

Customizations in service file

WorkingDirectory=/var/www/rubyapps/uwm-geoblacklight/current ExecStart=/usr/local/rvm/bin/rvm in /var/www/rubyapps/uwm-geoblacklight/current do bundle exec sidekiq -e production

  • Reload the systemctl daemon for the new created service

    sudo systemctl daemon-reload

  • Enable the sidekiq service:

    sudo systemctl enable sidekiq

  • Now we can start the Sidekiq service:

    sudo systemctl start|stop|restart sidekiq

If you have completed the last step, you have successfully created the sidekiq service and you can start using this.

Modify the sidekiq.service File

If you want to change the automatic restart behavior for Sidekiq:

  1. Open the sidekiq.service file in a text editor:

    sudo nano /etc/systemd/system/sidekiq.service
    
  2. Modify or add the Restart option. For example, to restart Sidekiq only if it fails, set it to on-failure, or set it to always to restart regardless of the stop condition:

    [Service]
    Type=simple
    ExecStart=/usr/local/bin/sidekiq -e production
    Restart=on-failure
    
  3. After making changes, reload the systemd configuration to apply the changes:

    sudo systemctl daemon-reload
    
  4. Optionally, restart the Sidekiq service to ensure the new configuration takes effect:

    sudo systemctl restart sidekiq
    

By setting Restart=on-failure or Restart=always, Sidekiq will restart automatically based on the specified conditions. If you want Sidekiq to stay stopped when you manually stop it, avoid setting Restart=always.