<!doctype html> <html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-development/developing" data-has-hydrated="false"> <head> <meta charset="UTF-8"> <meta name="generator" content="Docusaurus v3.1.0"> <title data-rh="true">Developing COSMOS | OpenC3 Docs</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://docs.openc3.com/tools/staticdocs/docs/development/developing"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Developing COSMOS | OpenC3 Docs"><meta data-rh="true" name="description" content="So you want to help develop COSMOS? All of our open source COSMOS code is on Github so the first thing to do is get an account. Next clone the COSMOS repository. We accept contributions from others as Pull Requests."><meta data-rh="true" property="og:description" content="So you want to help develop COSMOS? All of our open source COSMOS code is on Github so the first thing to do is get an account. Next clone the COSMOS repository. We accept contributions from others as Pull Requests."><link data-rh="true" rel="icon" href="/tools/staticdocs/img/favicon.png"><link data-rh="true" rel="canonical" href="https://docs.openc3.com/tools/staticdocs/docs/development/developing"><link data-rh="true" rel="alternate" href="https://docs.openc3.com/tools/staticdocs/docs/development/developing" hreflang="en"><link data-rh="true" rel="alternate" href="https://docs.openc3.com/tools/staticdocs/docs/development/developing" hreflang="x-default"><link rel="stylesheet" href="/tools/staticdocs/assets/css/styles.a9c55efa.css"> <script src="/tools/staticdocs/assets/js/runtime~main.c6bb8b5e.js" defer="defer"></script> <script src="/tools/staticdocs/assets/js/main.9ed8621d.js" defer="defer"></script> </head> <body class="navigation-with-keyboard"> <script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return localStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"dark")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_G6ar" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/tools/staticdocs/"><div class="navbar__logo"><img src="/tools/staticdocs/img/logo.svg" alt="OpenC3 Logo" class="themedComponent_DHUr themedComponent--light_DIHH"><img src="/tools/staticdocs/img/logo.svg" alt="OpenC3 Logo" class="themedComponent_DHUr themedComponent--dark_Bv2M"></div><b class="navbar__title text--truncate">OpenC3 Docs</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/tools/staticdocs/docs">Documentation</a><a href="https://openc3.com/enterprise/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Enterprise</a></div><div class="navbar__items navbar__items--right"><div class="navbarSearchContainer_bmvg"><div class="navbar__search"><span aria-label="expand searchbar" role="button" class="search-icon" tabindex="0"></span><input id="search_input_react" type="search" placeholder="Loading..." aria-label="Search" class="navbar__search-input search-bar" disabled=""></div></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_UyTV"><div class="docsWrapper_XLvK"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_z1FD" type="button"></button><div class="docRoot_HciC"><aside class="theme-doc-sidebar-container docSidebarContainer_e5ai"><div class="sidebarViewport_N8x0"><div class="sidebar_vJCc"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_qiME"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/tools/staticdocs/docs">Introduction</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/getting-started">Getting Started</a><button aria-label="Expand sidebar category 'Getting Started'" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/configuration">Configuration</a><button aria-label="Expand sidebar category 'Configuration'" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/tools">Tools</a><button aria-label="Expand sidebar category 'Tools'" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/guides">Guides</a><button aria-label="Expand sidebar category 'Guides'" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--active" aria-expanded="true" href="/tools/staticdocs/docs/development">Development</a><button aria-label="Collapse sidebar category 'Development'" type="button" class="clean-btn menu__caret"></button></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/curl">Testing with Curl</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/tools/staticdocs/docs/development/developing">Developing COSMOS</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/host-install">Host Install</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/json-api">JSON API</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/log-structure">Log Structure</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/roadmap">Roadmap</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/streaming-api">Streaming API</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/tools/staticdocs/docs/development/testing">Testing COSMOS</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="/tools/staticdocs/docs/meta">Meta</a><button aria-label="Expand sidebar category 'Meta'" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/tools/staticdocs/docs/privacy">OpenC3, Inc. Privacy Policy</a></li></ul></nav></div></div></aside><main class="docMainContainer_namt"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_YAwJ"><div class="docItemContainer_Rv5Z"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_zCmv" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/tools/staticdocs/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_JFrk"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item"><a class="breadcrumbs__link" itemprop="item" href="/tools/staticdocs/docs/development"><span itemprop="name">Development</span></a><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Developing COSMOS</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_O_Qc theme-doc-toc-mobile tocMobile_tjDr"><button type="button" class="clean-btn tocCollapsibleButton_htYj">On this page</button></div><div class="theme-doc-markdown markdown"><h1 id="developing-cosmos">Developing COSMOS</h1> <p>So you want to help develop COSMOS? All of our open source COSMOS code is on <a href="https://github.com/">Github</a> so the first thing to do is get an <a href="https://github.com/join">account</a>. Next <a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository">clone</a> the <a href="https://github.com/openc3/cosmos">COSMOS</a> repository. We accept contributions from others as <a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests">Pull Requests</a>.</p> <h2 id="development-tools">Development Tools</h2> <p>The core COSMOS team develops with the <a href="https://code.visualstudio.com/">Visual Studio Code</a> editor and we highly recommend it. We also utilize a number of extensions including docker, kubernetes, gitlens, prettier, eslint, python, vetur, and ruby. We commit our <code>openc3.code-workspace</code> configuration for VSCode to help configure these plugins. You also need <a href="https://www.docker.com/products/docker-desktop">Docker Desktop</a> which you should already have as it is a requirement to run COSMOS. You'll also need <a href="https://nodejs.org/en/download/">NodeJS</a> and <a href="https://yarnpkg.com/getting-started/install">yarn</a> installed.</p> <h1 id="building-cosmos">Building COSMOS</h1> <p>Note: We primarily develop COSMOS in MacOS so the commands here will reference bash scripts but the same files exist in Windows as batch scripts.</p> <p>Build COSMOS using the <code>openc3.sh</code> script:</p> <pre><code class="language-bash">% ./openc3.sh build </code></pre> <p>This will pull all the COSMOS container dependencies and build our local containers. Note: This can take a long time especially for your first build!</p> <p>Once the build completes you can see the built images with the following command:</p> <pre><code class="language-bash">% docker image ls | grep "openc3" openc3inc/openc3-cosmos-init latest 4cac7a3ea9d3 29 hours ago 446MB openc3inc/openc3-cosmos-script-runner-api latest 4aacbaf49f7a 29 hours ago 431MB openc3inc/openc3-cosmos-cmd-tlm-api latest 9a8806bd4be3 3 days ago 432MB openc3inc/openc3-operator latest 223e98129fe9 3 days ago 405MB openc3inc/openc3-base latest 98df5c0378c2 3 days ago 405MB openc3inc/openc3-redis latest 5a3003a49199 8 days ago 111MB openc3inc/openc3-traefik latest ec13a8d16a2f 8 days ago 104MB openc3inc/openc3-minio latest 787f6e3fc0be 8 days ago 238MB openc3inc/openc3-node latest b3ee86d3620a 8 days ago 372MB openc3inc/openc3-ruby latest aa158bbb9539 8 days ago 326MB </code></pre> <admonition title="Offline Building" type="info"><p>If you're building in a offline environment or want to use a private Rubygems, NPM or APK server (e.g. Nexus), you can update the following environment variables: RUBYGEMS_URL, NPM_URL, APK_URL, and more in the <a href="https://github.com/openc3/cosmos/blob/main/.env">.env</a> file. Example values:</p><p>ALPINE_VERSION=3.18<br> ALPINE_BUILD=6<br> RUBYGEMS_URL=<a href="https://rubygems.org">https://rubygems.org</a><br> NPM_URL=<a href="https://registry.npmjs.org">https://registry.npmjs.org</a><br> APK_URL=<a href="http://dl-cdn.alpinelinux.org">http://dl-cdn.alpinelinux.org</a><br></p></admonition> <h1 id="running-cosmos">Running COSMOS</h1> <p>Running COSMOS in development mode enables localhost access to internal API ports as well as sets <code>RAILS_ENV=development</code> in the cmd-tlm-api and script-runner-api Rails servers. To run in development mode:</p> <pre><code class="language-bash">% ./openc3.sh dev </code></pre> <p>You can now see the running containers (I removed CONTAINER ID, CREATED and STATUS to save space):</p> <pre><code class="language-bash">% docker ps IMAGE COMMAND PORTS NAMES openc3/openc3-cmd-tlm-api:latest "/sbin/tini -- rails…" 127.0.0.1:2901->2901/tcp cosmos-openc3-cmd-tlm-api-1 openc3/openc3-script-runner-api:latest "/sbin/tini -- rails…" 127.0.0.1:2902->2902/tcp cosmos-openc3-script-runner-api-1 openc3/openc3-traefik:latest "/entrypoint.sh trae…" 0.0.0.0:2900->80/tcp cosmos-openc3-traefik-1 openc3/openc3-operator:latest "/sbin/tini -- ruby …" cosmos-openc3-operator-1 openc3/openc3-minio:latest "/usr/bin/docker-ent…" 127.0.0.1:9000->9000/tcp cosmos-openc3-minio-1 openc3/openc3-redis:latest "docker-entrypoint.s…" 127.0.0.1:6379->6379/tcp cosmos-openc3-redis-1 </code></pre> <p>If you go to localhost:2900 you should see COSMOS up and running!</p> <h2 id="running-a-frontend-application">Running a Frontend Application</h2> <p>So now that you have COSMOS up and running how do you develop an individual COSMOS application?</p> <ol> <li>Bootstrap the frontend with yarn</li> </ol> <pre><code class="language-bash">openc3-init % yarn </code></pre> <ol> <li>Serve a local COSMOS application (CmdTlmServer, ScriptRunner, etc)</li> </ol> <pre><code class="language-bash">openc3-init % cd plugins/packages/openc3-tool-scriptrunner openc3-tool-scriptrunner % yarn serve DONE Compiled successfully in 128722ms App running at: - Local: http://localhost:2914/tools/scriptrunner/ - Network: http://localhost:2914/tools/scriptrunner/ Note that the development build is not optimized. To create a production build, run npm run build. </code></pre> <ol> <li> <p>Set the <a href="https://single-spa.js.org/">single SPA</a> override for the application</p> <p>Visit localhost:2900 and Right-click 'Inspect'<br> In the console paste:</p> </li> </ol> <pre><code class="language-javascript">localStorage.setItem("devtools", true); </code></pre> <p>Refresh and you should see <code>{...}</code> in the bottom right<br> Click the Default button next to the application (@openc3/tool-scriptrunner)<br> Paste in the development path which is dependent on the port returned by the local yarn serve and the tool name (scriptrunner)</p> <p><a href="http://localhost:2914/tools/scriptrunner/js/app.js">http://localhost:2914/tools/scriptrunner/js/app.js</a></p> <ol> <li>Refresh the page and you should see your local copy of the application (Script Runner in this example). If you dynamically add code (like <code>console.log</code>) the yarn window should re-compile and the browser should refresh displaying your new code. It is highly recommended to get familiar with your browser's <a href="https://developer.chrome.com/docs/devtools/overview/">development tools</a> if you plan to do frontend development.</li> </ol> <h2 id="running-a-backend-server">Running a Backend Server</h2> <p>If the code you want to develop is the cmd-tlm-api or script-runner-api backend servers there are several steps to enable access to a development copy.</p> <ol> <li>Run a development version of traefik. COSMOS uses traefik to direct API requests to the correct locations.</li> </ol> <pre><code class="language-bash">% cd openc3-traefik openc3-traefik % docker ps # Look for the container with name including traefik openc3-traefik % docker stop cosmos-openc3-traefik-1 openc3-traefik % docker build --build-arg TRAEFIK_CONFIG=traefik-dev.yaml -t openc3-traefik-dev . openc3-traefik % docker run --network=openc3-cosmos-network -p 2900:2900 -it --rm openc3-traefik-dev </code></pre> <ol> <li>Run a local copy of the cmd-tlm-api or script-runner-api</li> </ol> <pre><code class="language-bash">% cd openc3-cosmos-cmd-tlm-api openc3-cosmos-cmd-tlm-api % docker ps # Look for the container with name including cmd-tlm-api openc3-cosmos-cmd-tlm-api % docker stop cosmos-openc3-cosmos-cmd-tlm-api-1 # Run the following on Windows: openc3-cosmos-cmd-tlm-api> dev_server.bat # In Linux, set all the environment variables in the .env file, but override REDIS to be local openc3-cosmos-cmd-tlm-api % set -a; source ../.env; set +a openc3-cosmos-cmd-tlm-api % export OPENC3_REDIS_HOSTNAME=127.0.0.1 openc3-cosmos-cmd-tlm-api % export OPENC3_REDIS_EPHEMERAL_HOSTNAME=127.0.0.1 openc3-cosmos-cmd-tlm-api % bundle install openc3-cosmos-cmd-tlm-api % bundle exec rails s </code></pre> <ol> <li>Once the <code>bundle exec rails s</code> command returns you should see API requests coming from interations in the frontend code. If you add code (like Ruby debugging statements) to the cmd-tlm-api code you need to stop the server (CTRL-C) and restart it to see the effect.</li> </ol></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/OpenC3/cosmos/tree/main/docs.openc3.com/docs/development/developing.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_UohW" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_T23F"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/tools/staticdocs/docs/development/curl"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Testing with Curl</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/tools/staticdocs/docs/development/host-install"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Host Install</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_TN1Q thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#development-tools" class="table-of-contents__link toc-highlight">Development Tools</a></li><li><a href="#running-a-frontend-application" class="table-of-contents__link toc-highlight">Running a Frontend Application</a></li><li><a href="#running-a-backend-server" class="table-of-contents__link toc-highlight">Running a Backend Server</a></li></ul></div></div></div></div></main></div></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Homepage</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://openc3.com" target="_blank" rel="noopener noreferrer" class="footer__link-item">Home</a></li></ul></div><div class="col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/tools/staticdocs/docs">Documentation</a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://www.linkedin.com/company/openc3" target="_blank" rel="noopener noreferrer" class="footer__link-item">LinkedIn<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_awgD"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://github.com/OpenC3/cosmos" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_awgD"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/tools/staticdocs/docs/privacy">Privacy</a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2024 OpenC3, Inc.</div></div></div></footer></div> </body> </html>