PageSourceSearch

https://cromwellcms.com/assets/js/5ae735ed.a123e045.js

js cromwellcms.com collected 2026-10-04 13:31:16 UTC 14,477 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_cromwell_website=self.webpackChunk_cromwell_website||[]).push([[629],{6782:function(e,n,t){t.r(n),t.d(n,{frontMatter:function(){return i},contentTitle:function(){return p},metadata:function(){return s},toc:function(){return c},default:function(){return d}});var a=t(5773),r=t(808),o=(t(7378),t(5318)),l=["components"],i={sidebar_position:2},p="Installation",s={unversionedId:"overview/installation",id:"overview/installation",isDocsHomePage:!1,title:"Installation",description:"There are multiple ways to install and run Cromwell CMS",source:"@site/docs/overview/installation.md",sourceDirName:"overview",slug:"/overview/installation",permalink:"/docs/overview/installation",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Introduction",permalink:"/docs/overview/intro"},next:{title:"Configuration",permalink:"/docs/overview/configuration"}},c=[{value:"1. Docker run",id:"1-docker-run",children:[]},{value:"2. Docker compose",id:"2-docker-compose",children:[]},{value:"3. Cromwell CLI",id:"3-cromwell-cli",children:[]},{value:"4. NPM",id:"4-npm",children:[]}],m={toc:c};function d(e){var n=e.components,t=(0,r.Z)(e,l);return(0,o.kt)("wrapper",(0,a.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"installation"},"Installation"),(0,o.kt)("p",null,"There are multiple ways to install and run Cromwell CMS"),(0,o.kt)("h2",{id:"1-docker-run"},"1. Docker run"),(0,o.kt)("p",null,"The most simple way to deploy the CMS is to run it inside a Docker container. Our image goes with already installed MariaDB and Nginx (to proxy multiple services of the CMS), so you only need to install Docker.\n",(0,o.kt)("a",{parentName:"p",href:"https://docs.docker.com/engine/install/"},"You can install Docker on Windows, Linux, or another supported platform")),(0,o.kt)("p",null,"After installation run a single command in your terminal / command prompt to create and run a container:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"docker run -d -p 80:80 --name my-website cromwellcms/cromwell-mariadb:latest\n")),(0,o.kt)("p",null,"Open ",(0,o.kt)("a",{parentName:"p",href:"http://127.0.0.1/"},"http://127.0.0.1/")," if you installed locally or your web-server IP address in a web browser. For the first time system needs to run some configuration scripts, so it will be up and running under one minute.",(0,o.kt)("br",{parentName:"p"}),"\n","Open ",(0,o.kt)("a",{parentName:"p",href:"http://127.0.0.1/admin"},"http://127.0.0.1/admin")," to see the admin panel.  "),(0,o.kt)("p",null,"Note that you can use ",(0,o.kt)("inlineCode",{parentName:"p"},"localhost:port")," only in development, for production or local docker container open ",(0,o.kt)("inlineCode",{parentName:"p"},"127.0.0.1:port"),".  "),(0,o.kt)("p",null,"Stop the container: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"docker stop my-website\n")),(0,o.kt)("p",null,"Run again:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"docker start my-website\n")),(0,o.kt)("h2",{id:"2-docker-compose"},"2. Docker compose"),(0,o.kt)("p",null,"For more granular control you can configure a docker-compose file. For this scenario, we have another image that contains CMS and Nginx, without database.  "),(0,o.kt)("p",null,"Create a new directory and place ",(0,o.kt)("a",{parentName:"p",href:"https://docs.docker.com/compose/"},"docker-compose.yml")," file with the following content: "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title="docker-compose.yml"',title:'"docker-compose.yml"'},'version: "3"\nservices:\n\n  db:\n    image: mariadb:latest\n    container_name: mariadb_container\n    volumes: \n      - ./db_data:/var/lib/mysql\n    ports:\n      - 3306:3306\n    restart: unless-stopped\n    environment:\n      MYSQL_ROOT_PASSWORD: root_password\n      MYSQL_DATABASE: cromwell\n      MYSQL_USER: cromwell\n      MYSQL_PASSWORD: my_password\n\n  phpmyadmin:\n    depends_on:\n      - db\n    image: phpmyadmin/phpmyadmin\n    container_name: phpadmin_container\n    environment:\n      PMA_HOST: db\n    links:\n      - db:db\n    ports:\n      - 8081:80\n    restart: unless-stopped\n\n  cromwell:\n    image: cromwellcms/cromwell:latest\n    container_name: cromwell_container\n    depends_on:\n      - db\n    volumes:\n      - ./nginx:/app/nginx\n      - ./public:/app/public\n      - ./.cromwell/server:/app/.cromwell/server\n      - ./.cromwell/logs:/app/.cromwell/logs\n    ports:\n      - 80:80\n    restart: unless-stopped\n    environment:\n      DB_TYPE: mariadb\n      DB_HOST: db\n      DB_PORT: 3306\n      DB_DATABASE: cromwell\n      DB_USER: cromwell\n      DB_PASSWORD: my_password\n')),(0,o.kt)("p",null,"Apart from Cromwell CMS the file configures MariaDB and phpMyAdmin to run in separate containers (you can remove phpMyAdmin if you don't need it).",(0,o.kt)("br",{parentName:"p"}),"\n","Another key feature is that it has volumes, so all data will be stored in your current directory, outside of Docker 
1containers. You will be able to remove containers and keep DB data.  "),(0,o.kt)("p",null,"Replace password in environment variables: MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD, DB_PASSWORD.",(0,o.kt)("br",{parentName:"p"}),"\n","MYSQL_PASSWORD and DB_PASSWORD must have the same value  "),(0,o.kt)("p",null,"Start all services:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd /path/to/your/dir\ndocker-compose up -d\n")),(0,o.kt)("p",null,"Open ",(0,o.kt)("a",{parentName:"p",href:"http://127.0.0.1/"},"http://127.0.0.1/")," in a web browser to see your website.",(0,o.kt)("br",{parentName:"p"}),"\n","Open ",(0,o.kt)("a",{parentName:"p",href:"http://127.0.0.1/admin"},"http://127.0.0.1/admin")," to see the admin panel.",(0,o.kt)("br",{parentName:"p"}),"\n","Open ",(0,o.kt)("a",{parentName:"p",href:"http://127.0.0.1:8081"},"http://127.0.0.1:8081")," to see phpMyAdmin. "),(0,o.kt)("h4",{id:"working-directories"},"Working directories"),(0,o.kt)("p",null,"As you can see in your current directory appeared new files:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"db_data")," - To store MariaDB Database.   "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"public")," - For public content such as images and other files uploaded via file manager.   "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},".cromwell/logs")," - CMS logs.  "),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},".cromwell/server/emails")," - CMS e-mailing templates."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("inlineCode",{parentName:"li"},"nginx")," - Nginx settings.  ")),(0,o.kt)("p",null,"For example, if you want to change emailing template that sends to your customers when they place a new order in your store you can modify file at ",(0,o.kt)("inlineCode",{parentName:"p"},".cromwell/server/emails/order.hbs"),"  "),(0,o.kt)("p",null,"If you want to edit Nginx settings such as https configuration, you need to edit ",(0,o.kt)("inlineCode",{parentName:"p"},"nginx/nginx.conf")," and restart the container with CMS."),(0,o.kt)("h2",{id:"3-cromwell-cli"},"3. Cromwell CLI"),(0,o.kt)("p",null,"Cromwell CMS provides CLI that can create a new Node.js project. "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Download and install latest Node.js ",(0,o.kt)("strong",{parentName:"li"},"v14 or 16")," from ",(0,o.kt)("a",{parentName:"li",href:"https://nodejs.org/en/"},"https://nodejs.org/en/")),(0,o.kt)("li",{parentName:"ul"},"Install Python"),(0,o.kt)("li",{parentName:"ul"},"Install node-gyp: ",(0,o.kt)("inlineCode",{parentName:"li"},"npm install node-gyp -g"))),(0,o.kt)("p",null,"Navigate to a directory where you want to create a new project subdirectory and run:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx @cromwell/cli create my-website-name\n")),(0,o.kt)("p",null,"Run the CMS:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd my-website-name\nnpx cromwell start -d\n")),(0,o.kt)("p",null,"Open ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:4016"},(0,o.kt)("inlineCode",{parentName:"a"},"http://localhost:4016"))," in a web browser to see your web site.",(0,o.kt)("br",{parentName:"p"}),"\n","Open ",(0,o.kt)("a",{parentName:"p",href:"http://localhost:4016/admin"},(0,o.kt)("inlineCode",{parentName:"a"},"http://localhost:4016/admin"))," to see the admin panel.  "),(0,o.kt)("h4",{id:"working-directories-1"},"Working directories"),(0,o.kt)("p",null,"CMS will create the same working directories as in Docker compose example except ",(0,o.kt)("inlineCode",{parentName:"p"},"db_data")," and ",(0,o.kt)("inlineCode",{parentName:"p"},"nginx"),"."),(0,o.kt)("p",null,"In this example, we do not launch a proxy server (Nginx) or a database service, but Cromwell CMS can work without them as well as without any config.",(0,o.kt)("br",{parentName:"p"}),"\n","The CMS has its Node.js proxy to distribute traffic to API server, Next.js server and admin panel.  "),(0,o.kt)("p",null,"And if there's no config provided CMS will create and use a new SQLite database in ",(0,o.kt)("inlineCode",{parentName:"p"},"./.cromwell/server/db.sqlite3"),"   "),(0,o.kt)("div",{className:"admonition admonition-note alert alert--secondary"},(0,o.kt)("div",{parentName:"div",className:"admonition-heading"},(0,o.kt)("h5",{parentName:"div"},(0,o.kt)("span",{parentName:"h5",className:"admonition-icon"}
1,(0,o.kt)("svg",{parentName:"span",xmlns:"http://www.w3.org/2000/svg",width:"14",height:"16",viewBox:"0 0 14 16"},(0,o.kt)("path",{parentName:"svg",fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))),"note")),(0,o.kt)("div",{parentName:"div",className:"admonition-content"},(0,o.kt)("p",{parentName:"div"},"It's recommended to use SQLite only in development. For production, you have to switch to MySQL/MariaDB/PostgreSQL. Read in the ",(0,o.kt)("a",{parentName:"p",href:"/docs/overview/configuration"},"next post")," how to setup a database.  "))),(0,o.kt)("h2",{id:"4-npm"},"4. NPM"),(0,o.kt)("p",null,"Since the CMS is a set of packages, you can install them via npm.  "),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Download and install latest Node.js ",(0,o.kt)("strong",{parentName:"li"},"v14 or 16")," from ",(0,o.kt)("a",{parentName:"li",href:"https://nodejs.org/en/"},"https://nodejs.org/en/")),(0,o.kt)("li",{parentName:"ul"},"Install Python"),(0,o.kt)("li",{parentName:"ul"},"Install node-gyp: ",(0,o.kt)("inlineCode",{parentName:"li"},"npm install node-gyp -g"))),(0,o.kt)("p",null,"Create a new directory and open terminal/command prompt"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd /path/to/your/dir\n")),(0,o.kt)("p",null,"Run init command to create a new project:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npm init\n")),(0,o.kt)("p",null,"Install the CMS:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @cromwell/cms --exact\n")),(0,o.kt)("p",null,"You also can specify what themes and plugins your want to use. Usually we install the following by default (but you also will be able to install them later in the admin panel):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"yarn add @cromwell/theme-store @cromwell/theme-blog @cromwell/plugin-main-menu @cromwell/plugin-newsletter @cromwell/plugin-product-filter @cromwell/plugin-product-sh
1owcase @cromwell/plugin-stripe --exact\n")),(0,o.kt)("p",null,"Run the CMS:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"npx cromwell start -d\n")))}d.isMDXComponent=!0},5318:function(e,n,t){t.d(n,{Zo:function(){return c},kt:function(){return u}});var a=t(7378);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){r(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,a,r=function(e,n){if(null==e)return{};var t,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)t=o[a],n.indexOf(t)>=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)t=o[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var p=a.createContext({}),s=function(e){var n=a.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},c=function(e){var n=s(e.components);return a.createElement(p.Provider,{value:n},e.children)},m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=s(t),u=r,k=d["".concat(p,".").concat(u)]||d[u]||m[u]||o;return t?a.createElement(k,l(l({ref:n},c),{},{components:t})):a.createElement(k,l({ref:n},c))}));function u(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var o=t.length,l=new Array(o);l[0]=d;var i={};for(var p in n)hasOwnProperty.call(n,p)&&(i[p]=n[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var s=2;s<o;s++)l[s]=t[s];return a.createElement.apply(null,l)}return a.createElement.apply(null,t)}d.displayName="MDXCreateElement"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.