├── .dockerignore ├── test ├── Gemfile-native ├── Gemfile ├── Gemfile-git ├── test_gemfile_native.rb ├── test_gemfile.sh ├── test_gemfile_git.rb ├── test_gemfile.rb └── test_run.rb ├── .gitignore ├── CHANGELOG.md ├── .github └── workflows │ ├── manual_installer_test.yml │ └── docker-openstudio.yml ├── deploy_docker.sh ├── Dockerfile └── README.md /.dockerignore: -------------------------------------------------------------------------------- 1 | *.simg 2 | test/mygems 3 | -------------------------------------------------------------------------------- /test/Gemfile-native: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'ffi', '1.9.25' 4 | gem 'rubyXL', '3.3.29' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | build 3 | test/compact_osw 4 | docker-openstudio.simg 5 | test/.bundle 6 | test/mygems 7 | test/Gemfile*.lock 8 | 9 | -------------------------------------------------------------------------------- /test/Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'openstudio-standards', '0.2.2' 4 | gem 'tilt', '2.0.8' 5 | gem 'json_pure', '~> 2.1' -------------------------------------------------------------------------------- /test/Gemfile-git: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'openstudio-standards', github: 'nrel/openstudio-standards', branch: 'ambient-loop' 4 | gem 'tilt', github: 'rtomayko/tilt', ref: 'abe77eaf1b5f8da0a7e46135f' 5 | gem 'json_pure', '~> 2.1' 6 | -------------------------------------------------------------------------------- /test/test_gemfile_native.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | def local_gems 4 | Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name } 5 | end 6 | 7 | # list installed gems 8 | puts local_gems.map{ |name, specs| 9 | [name, specs.map{ |spec| spec.version.to_s }.join(',')].join(' ') 10 | } 11 | # test a gem that required native extensions 12 | require 'ffi' 13 | puts FFI::VERSION 14 | raise "FFI version does not match" unless FFI::VERSION == '1.9.25' 15 | 16 | require 'rubyXL' 17 | puts RubyXL::VERSION 18 | raise "RubyXL version does not match" unless RubyXL::VERSION == '3.3.29' 19 | -------------------------------------------------------------------------------- /test/test_gemfile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | rm -rf mygems 4 | rm -f Gemfile.lock 5 | bundle install --path mygems 6 | openstudio --loglevel Trace --bundle Gemfile --bundle_path mygems test_gemfile.rb 7 | 8 | rm -rf mygems 9 | rm -f Gemfile-git.lock 10 | bundle install --gemfile=Gemfile-git --path mygems 11 | openstudio --loglevel Trace --bundle Gemfile-git --bundle_path mygems test_gemfile_git.rb 12 | 13 | # rm -rf mygems 14 | # rm -f Gemfile-native.lock 15 | # bundle install --gemfile=Gemfile-native 16 | # openstudio --gem_path mygems/ruby/2.2.0 --gem_path mygems/ruby/2.2.0/bundler/gems execute_ruby_script test_gemfile_native.rb 17 | -------------------------------------------------------------------------------- /test/test_gemfile_git.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | def local_gems 4 | Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name } 5 | end 6 | 7 | # list installed gems 8 | puts local_gems.map{ |name, specs| 9 | [name, specs.map{ |spec| spec.version.to_s }.join(',')].join(' ') 10 | } 11 | 12 | # test a github checkout gem 13 | require 'tilt' 14 | puts Tilt::VERSION 15 | raise "Tilt version does not match" unless Tilt::VERSION == '2.0.8' 16 | 17 | require 'openstudio' 18 | require 'openstudio-standards' 19 | puts OpenstudioStandards::VERSION 20 | raise "OpenStudio Standards version does not match" unless OpenstudioStandards::VERSION == '0.5.0-ambient' 21 | -------------------------------------------------------------------------------- /test/test_gemfile.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | def local_gems 4 | Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.group_by{ |g| g.name } 5 | end 6 | 7 | # list installed gems 8 | puts local_gems.map{ |name, specs| 9 | [name, specs.map{ |spec| spec.version.to_s }.join(',')].join(' ') 10 | } 11 | # test a simple gem 12 | require 'tilt' 13 | puts Tilt::VERSION 14 | raise "Tilt version does not match" unless Tilt::VERSION == '2.0.8' 15 | 16 | # test a more complex / larger gem, that should override the existing version installed 17 | require 'openstudio' 18 | require 'openstudio-standards' 19 | puts OpenstudioStandards::VERSION 20 | raise "OpenStudio Standards version does not match" unless OpenstudioStandards::VERSION == '0.2.2' 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # OpenStudio Docker Images 2 | 3 | # Version 3.5.0 4 | TODO 5 | 6 | # Version 3.4.0 7 | TODO 8 | 9 | # Verison 3.3.0 10 | TODO 11 | 12 | ## Version 3.2.0 13 | TODO 14 | 15 | ## Version 3.1.0 16 | TODO 17 | 18 | ## Version 3.0.0 19 | TODO 20 | 21 | ## Version 2.9.0 22 | OpenStudio Version 2.9.0, without CLI target 23 | 24 | ## Version 2.8.1 25 | Enable pre-releases. Disable openstudio-cli images. 26 | 27 | ## Version 2.8.0 28 | Update to Ubuntu 16.04 Xenial. 29 | 30 | ## Version 2.7.1 31 | 32 | ## Version 2.7.0 33 | * Additional support for Singularity images. 34 | 35 | ## Versions 2.6.1, 2.6.2 36 | 37 | * Bundle install is run for OpenStudio Ruby gems. This enables the OpenStudio CLI (Oscli) to be run with the --bundle and --bundle_path options, which in turn enables the Oscli bundle to be updated. This capability is leveraged by OpenStudio Server and documented in that wiki. 38 | * Introduced multistage builds and nrel/openstudio-cli dockerhub images. These are smaller images that include only OpenStudio CLI dependencies, OpenStudio CLI, and EnergyPlus executable, copied from full OpenStudio base image. This corresponds to the "cli" target in the Dockerfile. 39 | * Support for Singularity images was introduced. 40 | 41 | ## Version 2.5.2 42 | 43 | * This has not been updated in quite some time. 44 | * OpenStudio 2.5.2 45 | * Add test for Radiance 46 | * Release latest docker image only from master branch 47 | 48 | ## Version 1.7.2 49 | 50 | * OpenStudio now depends on EnergyPlus 8.3. 51 | * Removed the installation of EnergyPlus on these images. The only EnergyPlus is the one provided by OpenStudio. 52 | 53 | ## Version 1.6.1 54 | 55 | * No longer publishing the Ruby specific versions. 56 | -------------------------------------------------------------------------------- /test/test_run.rb: -------------------------------------------------------------------------------- 1 | require 'openstudio' 2 | require 'rubygems' 3 | require 'fileutils' 4 | 5 | # Make sure we can load FFI as it is a very nice dependency 6 | begin 7 | gem 'ffi' 8 | require 'semantic' 9 | rescue LoadError 10 | system('gem install ffi') 11 | system('gem install semantic') 12 | Gem.clear_paths 13 | end 14 | 15 | # After installation, then it should be able to require ffi 16 | require 'ffi' 17 | 18 | # Install semantic to support checking versions easily. 19 | require 'semantic' 20 | require 'semantic/core_ext' 21 | 22 | puts "OpenStudio Version: #{OpenStudio.openStudioLongVersion}" 23 | 24 | # Should be able to require openstudio-standards, this is ignored for now. 25 | # require 'openstudio-standards' 26 | # standard = Standard.build("90.1-2004_SmallOffice") 27 | # puts standard 28 | 29 | # Make sure I can write out an example model 30 | puts OpenStudio::Model.exampleModel.to_s 31 | 32 | # Grab the test files that are shipped with OpenStudio and put into a folder and run 33 | FileUtils.rm_rf 'test/compact_osw' 34 | if OpenStudio.openStudioVersion.to_version >= '3.5.0'.to_version 35 | FileUtils.cp_r "/usr/local/openstudio-#{OpenStudio.openStudioVersion}/Examples/compact_osw", 'test/.' 36 | `/usr/local/bin/openstudio run -w test/compact_osw/compact_ruby_only.osw` 37 | elsif OpenStudio.openStudioVersion.to_version > '2.5.1'.to_version 38 | FileUtils.cp_r "/usr/local/openstudio-#{OpenStudio.openStudioVersion}/Examples/compact_osw", 'test/.' 39 | `/usr/local/bin/openstudio run -w test/compact_osw/compact.osw` 40 | else 41 | FileUtils.cp_r "/usr/Examples/compact_osw", 'test/.' 42 | `/usr/bin/openstudio run -w test/compact_osw/compact.osw` 43 | end 44 | raise "Simulation did not run" unless File.exist?('test/compact_osw/run/finished.job') 45 | -------------------------------------------------------------------------------- /.github/workflows/manual_installer_test.yml: -------------------------------------------------------------------------------- 1 | name: manual_update_develop 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | os_installer_link: 7 | description: 'The Link where to download the LINUX OpenStudio SDK Installer (.DEB)' 8 | required: true 9 | default: 'https://github.com/NREL/OpenStudio/releases/download/v3.4.0/OpenStudio-3.4.0+4bd816f785-Ubuntu-20.04.deb' 10 | os_version: 11 | description: 'OS version (e.g. 3.4.0). Must match .deb installer' 12 | required: true 13 | os_version_ext: 14 | description: 'OS version extension (e.g. -alpha). Must match .deb installer' 15 | required: false 16 | docker_image_tag: 17 | description: 'Docker image tag. Tag name will be prefixed with "dev-" unless tag = "develop"' 18 | required: true 19 | 20 | env: 21 | OPENSTUDIO_DOWNLOAD_URL: ${{ github.event.inputs.os_installer_link }} # required 22 | OPENSTUDIO_VERSION: ${{ github.event.inputs.os_version }} # required 23 | OPENSTUDIO_VERSION_EXT: ${{ github.event.inputs.os_version_ext }} # required 24 | DOCKER_MANUAL_IMAGE_TAG: ${{ github.event.inputs.docker_image_tag }} # required 25 | 26 | jobs: 27 | build_container: 28 | runs-on: ubuntu-24.04 29 | 30 | steps: 31 | - uses: actions/checkout@v4 32 | - uses: actions/setup-python@v5 33 | with: 34 | python-version: '3.11.x' 35 | 36 | - name: test and build 37 | shell: bash 38 | run: | 39 | set -x 40 | echo "Installer link: ${{ github.event.inputs.os_installer_link }}" 41 | echo "OS SDK Version: ${{ github.event.inputs.os_version }}" 42 | echo "OS SDK Version Extension: ${{ github.event.inputs.os_version_ext }}" 43 | echo "DOCKER IMAGE TAG: ${{ github.event.inputs.docker_image_tag }}" 44 | sudo apt update 45 | docker build --target base -t openstudio:latest \ 46 | --build-arg OPENSTUDIO_VERSION=$OPENSTUDIO_VERSION \ 47 | --build-arg OPENSTUDIO_VERSION_EXT=$OPENSTUDIO_VERSION_EXT \ 48 | --build-arg OPENSTUDIO_DOWNLOAD_URL=$OPENSTUDIO_DOWNLOAD_URL . 49 | docker run openstudio:latest openstudio openstudio_version 50 | docker run openstudio:latest /usr/local/openstudio-$OPENSTUDIO_VERSION/Radiance/bin/rtrace -version 51 | docker run -v $(pwd):/var/simdata/openstudio openstudio:latest ruby /var/simdata/openstudio/test/test_run.rb 52 | docker run -v $(pwd)/test:/var/simdata/openstudio openstudio:latest ./test_gemfile.sh 53 | 54 | - name: deploy docker 55 | if: ${{ success() }} 56 | shell: bash 57 | run: ./deploy_docker.sh 58 | env: 59 | DOCKER_PASS: ${{ secrets.DOCKER_PASS }} 60 | DOCKER_USER: ${{ secrets.DOCKER_USER }} 61 | -------------------------------------------------------------------------------- /deploy_docker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | IMAGETAG=${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT} 3 | echo "default image tag would be $IMAGETAG" 4 | IMAGETAG=skip 5 | DOCKER_REPO=${DOCKER_REPO:-nrel/openstudio} 6 | 7 | # Check branch name for correct tagging 8 | if [ "${GITHUB_REF}" == "refs/heads/develop" ]; then 9 | IMAGETAG="develop" 10 | elif [ "${GITHUB_REF}" == "refs/heads/2.9.X-LTS" ]; then 11 | IMAGETAG="2.9.X-LTS" 12 | elif [ "${GITHUB_REF}" == "refs/heads/master" ]; then 13 | # Retrieve the version number from rails 14 | IMAGETAG=${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT} 15 | # Uncomment and set branch name for custom builds. 16 | elif [ "${GITHUB_REF}" == "refs/heads/custom_branch_name" ]; then 17 | IMAGETAG="experimental" 18 | elif [ "${DOCKER_MANUAL_IMAGE_TAG}" == "develop" ]; then 19 | IMAGETAG="develop" 20 | fi 21 | 22 | # Check if this is a manual installer GH action 23 | if [ ! -z "${DOCKER_MANUAL_IMAGE_TAG}" ]; then 24 | if [ "${DOCKER_MANUAL_IMAGE_TAG}" == "develop" ]; then 25 | IMAGETAG="develop" 26 | else 27 | IMAGETAG="dev-${DOCKER_MANUAL_IMAGE_TAG}" 28 | fi 29 | fi 30 | 31 | # GITHUB_BASE_REF is only set on Pull Request events. Do not build those 32 | if [ "${IMAGETAG}" != "skip" ] && [[ -z "${GITHUB_BASE_REF}" ]]; then 33 | echo "Tagging image as $IMAGETAG and pushing to ${DOCKER_REPO}" 34 | 35 | echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin 36 | # Tag versioned image 37 | docker tag openstudio:latest ${DOCKER_REPO}:$IMAGETAG; (( exit_status = exit_status || $? )) 38 | 39 | # Only update and push 'latest' if this is a stable release (no extension) 40 | if [ -z "${OPENSTUDIO_VERSION_EXT}" ]; then 41 | echo "Stable release detected. Updating and pushing '${DOCKER_REPO}:latest'" 42 | docker tag openstudio:latest ${DOCKER_REPO}:latest; (( exit_status = exit_status || $? )) 43 | docker push ${DOCKER_REPO}:latest; (( exit_status = exit_status || $? )) 44 | else 45 | echo "Pre-release detected (extension: '${OPENSTUDIO_VERSION_EXT}'). Skipping 'latest' tag update." 46 | fi 47 | 48 | # Push versioned tag 49 | docker push ${DOCKER_REPO}:$IMAGETAG; (( exit_status = exit_status || $? )) 50 | # If on develop branch, also push the develop tag pointing to this image 51 | if [ "${IMAGETAG}" == "develop" ] || [ "${GITHUB_REF}" == "refs/heads/develop" ]; then 52 | docker tag openstudio:latest ${DOCKER_REPO}:develop; (( exit_status = exit_status || $? )) 53 | docker push ${DOCKER_REPO}:develop; (( exit_status = exit_status || $? )) 54 | fi 55 | 56 | exit $exit_status 57 | else 58 | echo "Not on a deployable branch, this is a pull request or has been explicity skipped" 59 | fi 60 | -------------------------------------------------------------------------------- /.github/workflows/docker-openstudio.yml: -------------------------------------------------------------------------------- 1 | name: openstudio-docker 2 | 3 | on: [push, pull_request] 4 | 5 | # example of how to restrict to one branch and push event 6 | #on: 7 | # push: 8 | # branches: 9 | # - test_branch 10 | 11 | concurrency: 12 | group: openstudio-docker-${{ github.ref }} 13 | cancel-in-progress: true 14 | 15 | env: 16 | USE_TESTING_TIMEOUTS: "true" 17 | OPENSTUDIO_VERSION: 3.11.0 18 | OPENSTUDIO_SHA: dee62bf9dd 19 | OPENSTUDIO_VERSION_EXT: "-rc1" 20 | OPENSTUDIO_DOWNLOAD_URL: "https://openstudio-ci-builds.s3-us-west-2.amazonaws.com/develop/OpenStudio-3.11.0-rc1%2Bdee62bf9dd-Ubuntu-22.04-x86_64.deb" 21 | 22 | permissions: 23 | contents: read 24 | 25 | jobs: 26 | docker: 27 | runs-on: ubuntu-24.04 28 | steps: 29 | - uses: actions/checkout@v4 30 | - uses: actions/setup-python@v5 31 | with: 32 | python-version: '3.12.x' 33 | 34 | - name: test and build 35 | shell: bash 36 | run: | 37 | set -euo pipefail 38 | docker build -t openstudio:latest \ 39 | --build-arg OPENSTUDIO_VERSION=$OPENSTUDIO_VERSION \ 40 | --build-arg OPENSTUDIO_SHA=$OPENSTUDIO_SHA \ 41 | --build-arg OPENSTUDIO_VERSION_EXT=$OPENSTUDIO_VERSION_EXT . 42 | docker run openstudio:latest openstudio openstudio_version 43 | docker run openstudio:latest /usr/local/openstudio-$OPENSTUDIO_VERSION/Radiance/bin/rtrace -version 44 | docker run -v "$(pwd)":/var/simdata/openstudio openstudio:latest ruby /var/simdata/openstudio/test/test_run.rb 45 | docker run -v "$(pwd)/test":/var/simdata/openstudio openstudio:latest ./test_gemfile.sh 46 | 47 | - name: deploy docker 48 | if: ${{ success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/custom_branch_name') }} 49 | shell: bash 50 | run: | 51 | set -euo pipefail 52 | ./deploy_docker.sh 53 | env: 54 | DOCKER_PASS: ${{ secrets.DOCKER_PASS }} 55 | DOCKER_USER: ${{ secrets.DOCKER_USER }} 56 | 57 | apptainer: 58 | runs-on: ubuntu-24.04 59 | needs: docker 60 | if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/custom_branch_name' }} 61 | permissions: 62 | contents: read 63 | id-token: write 64 | steps: 65 | - uses: actions/checkout@v4 66 | - uses: actions/setup-python@v5 67 | with: 68 | python-version: '3.12.x' 69 | 70 | - name: install apptainer 71 | shell: bash 72 | run: | 73 | set -euo pipefail 74 | sudo add-apt-repository -y ppa:apptainer/ppa 75 | sudo apt update 76 | sudo apt install -y apptainer 77 | 78 | - name: build apptainer 79 | shell: bash 80 | run: | 81 | set -euo pipefail 82 | apptainer build \ 83 | OpenStudio-$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT.$OPENSTUDIO_SHA-Apptainer.sif \ 84 | docker://nrel/openstudio:$OPENSTUDIO_VERSION$OPENSTUDIO_VERSION_EXT 85 | 86 | - uses: actions/upload-artifact@v4 87 | with: 88 | name: apptainer-image 89 | path: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif 90 | 91 | - name: Configure AWS credentials 92 | uses: aws-actions/configure-aws-credentials@v3 93 | with: 94 | aws-region: ${{ secrets.AWS_DEFAULT_REGION }} 95 | role-to-assume: arn:aws:iam::471211731895:role/OpenStudioGitHubActionsRole 96 | role-session-name: GitHubActions 97 | 98 | - name: Upload artifacts to AWS S3 99 | uses: usualdesigner/s3-artifact-upload@main 100 | with: 101 | bucket-name: openstudio-builds 102 | prefix: ${{ env.OPENSTUDIO_VERSION }} 103 | file: OpenStudio-${{ env.OPENSTUDIO_VERSION }}${{ env.OPENSTUDIO_VERSION_EXT }}.${{ env.OPENSTUDIO_SHA }}-Apptainer.sif 104 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 AS base 2 | 3 | LABEL maintainer="Nicholas Long nicholas.long@nrel.gov" 4 | 5 | # Set the version of OpenStudio when building the container. For example `docker build --build-arg 6 | ARG OPENSTUDIO_VERSION=3.11.0 7 | ARG OPENSTUDIO_VERSION_EXT="-rc1" 8 | ARG OPENSTUDIO_SHA="dee62bf9dd" 9 | # If OPENSTUDIO_DOWNLOAD_URL is not provided, construct a reasonable default using the 10 | # OpenStudio CI S3 pattern. Users can override by passing --build-arg OPENSTUDIO_DOWNLOAD_URL=... 11 | ARG OPENSTUDIO_DOWNLOAD_URL="" 12 | ENV RC_RELEASE=TRUE 13 | ENV OS_BUNDLER_VERSION=2.4.10 14 | ENV RUBY_VERSION=3.2.2 15 | ENV BUNDLE_WITHOUT=native_ext 16 | 17 | # Install gdebi, then download and install OpenStudio, then clean up. 18 | # gdebi handles the installation of OpenStudio's dependencies 19 | 20 | # install locales and set to en_US.UTF-8. This is needed for running the CLI on some machines 21 | # such as singularity. 22 | RUN apt-get update && apt-get install -y \ 23 | curl \ 24 | gdebi-core \ 25 | libsqlite3-dev \ 26 | libssl-dev \ 27 | libffi-dev \ 28 | build-essential \ 29 | zlib1g-dev \ 30 | vim \ 31 | git \ 32 | locales \ 33 | sudo \ 34 | && if [ -z "${OPENSTUDIO_DOWNLOAD_URL}" ]; then \ 35 | ESC_VERSION=$(echo "${OPENSTUDIO_VERSION}${OPENSTUDIO_VERSION_EXT}" | sed 's/+/%2B/g'); \ 36 | if [ -n "${OPENSTUDIO_SHA}" ]; then \ 37 | OPENSTUDIO_DOWNLOAD_URL="https://openstudio-ci-builds.s3.amazonaws.com/develop/OpenStudio-${ESC_VERSION}%2B${OPENSTUDIO_SHA}-Ubuntu-22.04-x86_64.deb"; \ 38 | else \ 39 | OPENSTUDIO_DOWNLOAD_URL="https://openstudio-ci-builds.s3.amazonaws.com/develop/OpenStudio-${ESC_VERSION}-Ubuntu-22.04-x86_64.deb"; \ 40 | fi; \ 41 | fi \ 42 | && echo "OpenStudio Package Download URL is ${OPENSTUDIO_DOWNLOAD_URL}" \ 43 | && curl -SLO "$OPENSTUDIO_DOWNLOAD_URL" \ 44 | && OPENSTUDIO_DOWNLOAD_FILENAME=$(ls *.deb) \ 45 | # Verify that the download was successful (not access denied XML from s3) 46 | && grep -v -q "AccessDenied" ${OPENSTUDIO_DOWNLOAD_FILENAME} \ 47 | && gdebi -n $OPENSTUDIO_DOWNLOAD_FILENAME \ 48 | # Cleanup 49 | && rm -f $OPENSTUDIO_DOWNLOAD_FILENAME \ 50 | && rm -rf /var/lib/apt/lists/* \ 51 | && locale-gen en_US en_US.UTF-8 \ 52 | && dpkg-reconfigure locales 53 | 54 | RUN apt update && apt install -y libyaml-dev ruby-full 55 | # RUN apt-get install ca-certificates 56 | RUN pwd 57 | RUN curl -SLO -k https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz \ 58 | && tar -xvzf ruby-3.2.2.tar.gz \ 59 | && cd ruby-3.2.2 \ 60 | && ./configure \ 61 | && make && make install 62 | 63 | ## Detect the OpenStudio installation folder 64 | ## The folder will be openstudio-3.9.0 or something like openstudio-3.9.0-alpha 65 | ## We search for any folder matching the version pattern to handle various naming conventions 66 | 67 | RUN echo "Searching for OpenStudio installation..." \ 68 | && ls -la /usr/local \ 69 | && ls -la /usr \ 70 | && OPENSTUDIO_FOLDER=$(find /usr -maxdepth 2 -type d -name "openstudio-${OPENSTUDIO_VERSION}*" 2>/dev/null | head -1) \ 71 | && if [ -z "$OPENSTUDIO_FOLDER" ]; then \ 72 | echo "ERROR: OpenStudio folder not found matching pattern openstudio-${OPENSTUDIO_VERSION}*"; \ 73 | echo "Searching for any openstudio folder..."; \ 74 | find /usr -maxdepth 2 -type d -name "openstudio-*" 2>/dev/null; \ 75 | exit 1; \ 76 | fi \ 77 | && echo "OpenStudio folder is ${OPENSTUDIO_FOLDER}" \ 78 | && ls -la ${OPENSTUDIO_FOLDER} \ 79 | && rm -rf ruby* \ 80 | && gem install bundler -v $OS_BUNDLER_VERSION \ 81 | && gem install zip \ 82 | && mkdir /var/oscli \ 83 | && cp ${OPENSTUDIO_FOLDER}/Ruby/Gemfile /var/oscli/ \ 84 | && cp ${OPENSTUDIO_FOLDER}/Ruby/Gemfile.lock /var/oscli/ \ 85 | && cp ${OPENSTUDIO_FOLDER}/Ruby/openstudio-gems.gemspec /var/oscli/ \ 86 | && ln -s ${OPENSTUDIO_FOLDER} /usr/local/openstudio-${OPENSTUDIO_VERSION} 87 | 88 | ENV RUBYLIB=/usr/local/openstudio-${OPENSTUDIO_VERSION}/Ruby 89 | ENV ENERGYPLUS_EXE_PATH=/usr/local/openstudio-${OPENSTUDIO_VERSION}/EnergyPlus/energyplus 90 | 91 | RUN rm -rf ruby* 92 | ## Add RUBYLIB link for openstudio.rb 93 | ENV RUBYLIB=/usr/local/openstudio-${OPENSTUDIO_VERSION}/Ruby 94 | ENV ENERGYPLUS_EXE_PATH=/usr/local/openstudio-${OPENSTUDIO_VERSION}/EnergyPlus/energyplus 95 | 96 | WORKDIR /var/oscli 97 | RUN bundle -v 98 | RUN bundle _${OS_BUNDLER_VERSION}_ install --path=gems --without=native_ext --jobs=4 --retry=3 99 | 100 | # Configure the bootdir & confirm that openstudio is able to load the bundled gem set in /var/gemdata 101 | VOLUME /var/simdata/openstudio 102 | WORKDIR /var/simdata/openstudio 103 | RUN openstudio --loglevel Trace --bundle /var/oscli/Gemfile --bundle_path /var/oscli/gems --bundle_without native_ext gem_list 104 | 105 | # May need this for syscalls that do not have ext in path 106 | 107 | CMD [ "/bin/bash" ] 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenStudio 2 | 3 | [![openstudio-docker](https://github.com/NREL/docker-openstudio/actions/workflows/docker-openstudio.yml/badge.svg)](https://github.com/NREL/docker-openstudio/actions/workflows/docker-openstudio.yml) 4 | 5 | This repo provides a container for OpenStudio as well as several dependencies, including Ruby 2.x, Bundler, 6 | build-essentials and various development libraries for gem support. 7 | 8 | At the moment, there is only one target container for this project, however, we are working on containers for a 9 | slim version and a version compatible with [Singularity](https://singularity.lbl.gov). 10 | 11 | ## Docker Tags 12 | 13 | Below is a table of the various docker tags and their meanings as seen on [this page](https://hub.docker.com/r/nrel/openstudio/tags/). 14 | 15 | | Tag | Description | 16 | |---------|-----------------------------------------------------------------------------------------| 17 | | x.y.z | Build of official OpenStudio release (recommended use) | 18 | | latest | Latest official release of OpenStudio (e.g. 2.5.1) | 19 | | develop | Release of [develop branch](https://github.com/NREL/docker-openstudio/tree/develop) | 20 | 21 | ## Building OpenStudio Container 22 | 23 | These images are automatically built in TravisCI. To trigger TravisCI for a new build do the following: 24 | 25 | * On develop branch update the [.travis.yml](.travis.yml) with the new version of OpenStudio and SHA 26 | 27 | ```yaml 28 | - OPENSTUDIO_VERSION: 2.6.0 29 | - OPENSTUDIO_SHA: e3cb91f98a 30 | ``` 31 | * Push changes to the feature branch, make and merge a pull request to develop 32 | * Wait for CI to finish and verify new develop image is available on [docker hub](https://hub.docker.com/r/nrel/openstudio/tags/). 33 | * Test locally (if needed) 34 | 35 | ```bash 36 | docker pull nrel/openstudio:develop 37 | docker run -it --rm nrel/openstudio:develop bash 38 | irb 39 | require 'openstudio' 40 | puts OpenStudio.getOpenStudioCLI 41 | ``` 42 | 43 | ### Build Locally 44 | 45 | Begin by installing the [docker toolkit](https://docs.docker.com/engine/installation/) version 17.03.1 or later, as 46 | described in the linked documentation. Once the toolkit is installed and activated, run the command below to build the base image with OpenStudio 2.6.1. 47 | 48 | ``` 49 | docker build --target base -t openstudio-local --build-arg OPENSTUDIO_VERSION=2.6.1 --build-arg OPENSTUDIO_SHA=ab0dddde0b . 50 | ``` 51 | 52 | The version of OpenStudio and the SHAs are listed [here](https://github.com/NREL/OpenStudio/wiki/OpenStudio-Version-Compatibility-Matrix). 53 | 54 | If the `--target` is not passed, then the docker build will contain only the CLI. 55 | 56 | ## Executing OpenStudio Container 57 | 58 | There are two options to acquire the docker container required for execution. Both assume that the 59 | [docker tool-kit](https://docs.docker.com/engine/installation/) version 17.03.1 or later is installed. The first option, 60 | building the container from a GitHub checkout, is outlined above. Additionally, it is typically easiest to 61 | [tag the resulting container](https://docs.docker.com/engine/reference/commandline/tag/) as `nrel/openstudio:latest`. 62 | For a more extensive discussion of the latest tag and associated best practices 63 | [please refer to this Medium article](https://medium.com/@mccode/the-misunderstood-docker-tag-latest-af3babfd6375). 64 | The second option, downloading a release from DockerHub, requires determining the 65 | [docker-openstudio tagged release](https://hub.docker.com/r/nrel/openstudio/tags/) that is desired, and then running 66 | `docker pull nrel/openstudio:`. As an example, to download the 2.1.1 docker-openstudio image, the command would 67 | be `docker pull nrel/openstudio:2.1.1`. 68 | 69 | Once the desired container is available, either through a build or pull process, the next step is to run the container. 70 | To simply access the container tagged with 'tag', (where tag was respectively 'latest' or '2.1.1' in the above 71 | paragraph,) run `docker run -it --rm nrel/openstudio:tag /bin/bash`. 72 | 73 | To execute an OpenStudio Workflow directly from the command line requires 74 | [mounting the requisite files to the container](https://docs.docker.com/engine/reference/run/#volume-shared-filesystems), 75 | as well as invoking the [OpenStudio CLI](https://nrel.github.io/OpenStudio-user-documentation/reference/command_line_interface/) 76 | (command line interface.) The docker container by default executes commands in the `/var/simdata/openstudio` directory, 77 | (this is defined in the [Dockerfile](./Dockerfile).) If the desired OSW was located at 78 | `/Users/myuser/demo_os_files/example.osw` on the host computer, the appropriate docker command to execute the OSW would 79 | be `docker run -it --rm -v=/Users/myuser/demo_os_files:/var/simdata/openstudio nrel/openstudio /usr/bin/openstudio run -w example.osw` 80 | 81 | If gem dependencies are required as part of the CLI outside of those 82 | [packed with OpenStudio](https://github.com/NREL/OpenStudio/blob/develop/dependencies/ruby/Gemfile) please contact 83 | Kyle Benne, Ry Horsey, and Dan Macumber at their NREL email addresses. 84 | 85 | # Issues 86 | 87 | Please submit issues on the project's [Github](https://github.com/nrel/docker-openstudio) page. 88 | 89 | ## Building and publishing specific OpenStudio versions 90 | 91 | - **Local build for a specific version (example: 3.11.0-alpha):** 92 | 93 | ```bash 94 | docker build -t openstudio:latest \ 95 | --build-arg OPENSTUDIO_VERSION=3.11.0 \ 96 | --build-arg OPENSTUDIO_VERSION_EXT="-alpha" \ 97 | --build-arg OPENSTUDIO_SHA= . 98 | ``` 99 | 100 | - **Tag and push locally (optional):** 101 | 102 | ```bash 103 | docker tag openstudio:latest yourrepo/openstudio:3.11.0-alpha 104 | docker push yourrepo/openstudio:3.11.0-alpha 105 | ``` 106 | 107 | - **Trigger GitHub Actions build to publish to Docker Hub:** 108 | 109 | - Update `.github/workflows/docker-openstudio.yml` env values for `OPENSTUDIO_VERSION`, `OPENSTUDIO_VERSION_EXT`, and `OPENSTUDIO_SHA` on a branch. 110 | - Create a pull request to `develop` and merge; the workflow will build and, if on `develop`, push the image to Docker Hub as the `develop` tag (and `latest`). 111 | 112 | Notes: 113 | 114 | - The `deploy_docker.sh` script tags images pushed to Docker Hub. You can override `DOCKER_REPO` for testing private repos. 115 | - If `OPENSTUDIO_SHA` is empty, the downloader will attempt to use a generic S3 URL without the SHA. 116 | --------------------------------------------------------------------------------