{"ArticleId":null,"Name":"Installing GrandNode","Content":"\u003Cp\u003EThere are three ways to get GrandNode running: the Docker image (fastest, nothing to build), a release package from GitHub (a stable version you build yourself), or a clone of the repository (for development). All three end in the same place \u2014 the \u003Ca href=\u0022/getting-started-installation-wizard\u0022\u003Einstallation wizard\u003C/a\u003E in your browser, where you connect the database and create the administrator account.\u003C/p\u003E\n\n\u003Ch2 id=\u0022choose-a-version\u0022\u003EChoose a version\u003C/h2\u003E\n\u003Cp\u003EThe \u003Ccode\u003Emain\u003C/code\u003E branch and the GitHub releases contain the stable version. The \u003Ccode\u003Edevelop\u003C/code\u003E branch is the development version and may be unstable \u2014 use it only to try new features. Docker images follow the same split: \u003Ccode\u003Egrandnode/grandnode2:latest\u003C/code\u003E is built from \u003Ccode\u003Emain\u003C/code\u003E, specific versions are tagged with their number.\u003C/p\u003E\n\n\u003Ch2 id=\u0022install-with-docker\u0022\u003EInstall with Docker\u003C/h2\u003E\n\u003Cp\u003EYou need Docker. The two commands below start MongoDB and GrandNode in separate containers:\u003C/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Edocker run -d -p 127.0.0.1:27017:27017 --name mongodb mongo\ndocker run -d -p 80:8080 --name grandnode2 --link mongodb:mongo \\\n  -v grandnode_images:/app/wwwroot/assets/images \\\n  -v grandnode_appdata:/app/App_Data \\\n  grandnode/grandnode2\u003C/code\u003E\u003C/pre\u003E\n\u003Col\u003E\n\u003Cli\u003ERun the first command to start MongoDB. It listens only on the local interface of the host.\u003C/li\u003E\n\u003Cli\u003ERun the second command. GrandNode listens on port 8080 inside the container, published as port 80 on the host. \u003Ccode\u003E--link mongodb:mongo\u003C/code\u003E makes the database reachable from GrandNode under the host name \u003Ccode\u003Emongo\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003EThe two volumes keep uploaded product images and \u003Ccode\u003EApp_Data\u003C/code\u003E (which holds \u003Ccode\u003ESettings.cfg\u003C/code\u003E with the database connection) when the container is recreated. Do not skip them. This is enough for a trial; for production - connection string from an environment variable, which folders to keep, several replicas and Redis - see \u003Ca href=\u0022/getting-started-docker-kubernetes\u0022\u003ERunning in production: Docker and Kubernetes\u003C/a\u003E.\u003C/li\u003E\n\u003Cli\u003EOpen \u003Ccode\u003Ehttp://localhost/\u003C/code\u003E. You are redirected to \u003Ccode\u003E/install\u003C/code\u003E. In the wizard enter \u003Ccode\u003Emongo\u003C/code\u003E as the \u003Cstrong\u003EMongoDB Server name\u003C/strong\u003E and any database name, for example \u003Ccode\u003Egrandnode\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003EAfter the wizard reports success, restart the container: \u003Ccode\u003Edocker restart grandnode2\u003C/code\u003E.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003ETo pin a release instead of \u003Ccode\u003Elatest\u003C/code\u003E, pull it by number: \u003Ccode\u003Edocker pull grandnode/grandnode2:x.xx\u003C/code\u003E, and use that tag in \u003Ccode\u003Edocker run\u003C/code\u003E.\u003C/p\u003E\n\n\u003Ch2 id=\u0022install-from-a-release-package\u0022\u003EInstall from a release package\u003C/h2\u003E\n\u003Col\u003E\n\u003Cli\u003EInstall the .NET 10 SDK and MongoDB (see \u003Ca href=\u0022/getting-started-system-requirements\u0022\u003ESystem requirements\u003C/a\u003E).\u003C/li\u003E\n\u003Cli\u003EDownload the source code package of the version you want from the \u003Ca href=\u0022https://github.com/grandnode/grandnode2/releases\u0022\u003EReleases page on GitHub\u003C/a\u003E and extract it.\u003C/li\u003E\n\u003Cli\u003EIn the extracted folder build the whole solution. This also compiles every module and plugin and copies them into the web project\u0027s output:\n\u003Cpre\u003E\u003Ccode\u003Edotnet build GrandNode.slnx\u003C/code\u003E\u003C/pre\u003E\u003C/li\u003E\n\u003Cli\u003EStart the web project:\n\u003Cpre\u003E\u003Ccode\u003Edotnet run --project src/Web/Grand.Web\u003C/code\u003E\u003C/pre\u003E\u003C/li\u003E\n\u003Cli\u003EOpen the address printed in the console (the Kestrel profile uses \u003Ccode\u003Ehttps://localhost:5001\u003C/code\u003E and \u003Ccode\u003Ehttp://localhost:5000\u003C/code\u003E) and complete the wizard.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003EAlways build the solution, not only \u003Ccode\u003EGrand.Web\u003C/code\u003E: the web project does not reference the plugins, they install themselves into its output when they are built.\u003C/p\u003E\n\n\u003Ch2 id=\u0022install-from-source\u0022\u003EInstall from source\u003C/h2\u003E\n\u003Cpre\u003E\u003Ccode\u003Egit clone https://github.com/grandnode/grandnode2.git\ncd grandnode2\ndotnet build GrandNode.slnx\ndotnet run --project src/Web/Grand.Web\u003C/code\u003E\u003C/pre\u003E\n\u003Cp\u003EOr open \u003Ccode\u003EGrandNode.slnx\u003C/code\u003E in Visual Studio or Rider, build the solution, set \u003Ccode\u003EGrand.Web\u003C/code\u003E as the startup project and run it. Both launch profiles set \u003Ccode\u003EASPNETCORE_ENVIRONMENT=Development\u003C/code\u003E. If you start the application another way in development, set that variable yourself \u2014 without it the files under \u003Ccode\u003E_content/...\u003C/code\u003E return 404 and the Admin panel loads without CSS and JavaScript.\u003C/p\u003E\n\n\u003Ch2 id=\u0022host-on-linux\u0022\u003EHost on a Linux server\u003C/h2\u003E\n\u003Cp\u003EInstall nginx, the .NET 10 SDK and MongoDB, then build and publish. Modules and plugins must be built before the publish step, because each one copies itself into the web project\u0027s output:\u003C/p\u003E\n\u003Cpre\u003E\u003Ccode\u003Egit clone -b x.xx https://github.com/grandnode/grandnode2.git ~/source/grandnode\ncd ~/source/grandnode\ndotnet restore GrandNode.slnx\nfor module in src/Modules/*; do dotnet build \u0022$module\u0022 -c Release; done\nfor plugin in src/Plugins/*; do dotnet build \u0022$plugin\u0022 -c Release; done\ndotnet publish src/Web/Grand.Web -c Release -o /var/webapps/grandnode\u003C/code\u003E\u003C/pre\u003E\n\u003Cp\u003ERun it as a service with a systemd unit whose \u003Ccode\u003EWorkingDirectory\u003C/code\u003E is \u003Ccode\u003E/var/webapps/grandnode\u003C/code\u003E and whose \u003Ccode\u003EExecStart\u003C/code\u003E is \u003Ccode\u003E/usr/bin/dotnet /var/webapps/grandnode/Grand.Web.dll\u003C/code\u003E, with \u003Ccode\u003ERestart=always\u003C/code\u003E and \u003Ccode\u003EUser=www-data\u003C/code\u003E. Point nginx at the application and set \u003Ccode\u003ESecurity:UseForwardedHeaders\u003C/code\u003E to \u003Ccode\u003Etrue\u003C/code\u003E in \u003Ccode\u003EApp_Data/appsettings.json\u003C/code\u003E so links and redirects use your public HTTPS address.\u003C/p\u003E\n\n\u003Ch2 id=\u0022supplying-the-connection-string-up-front\u0022\u003ESupplying the connection string up front\u003C/h2\u003E\n\u003Cp\u003EFor automated deployments you can put the MongoDB connection string in \u003Ccode\u003Eappsettings.json\u003C/code\u003E under \u003Ccode\u003EConnectionStrings:Mongodb\u003C/code\u003E (or the environment variable \u003Ccode\u003EConnectionStrings__Mongodb\u003C/code\u003E). The wizard then hides the database fields and asks only for the administrator account, the collation and sample data, and it does not write \u003Ccode\u003ESettings.cfg\u003C/code\u003E.\u003C/p\u003E\n\n\u003Ch2 id=\u0022tips-and-common-mistakes\u0022\u003ETips and common mistakes\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003EAdmin panel without styles\u003C/strong\u003E \u2014 the application runs without \u003Ccode\u003EASPNETCORE_ENVIRONMENT=Development\u003C/code\u003E on a development build. Set the variable or publish a Release build.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EA plugin is missing\u003C/strong\u003E \u2014 the solution or that plugin was not built. Build it; plugin views are compiled into the plugin DLL.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003ELocked DLL during build\u003C/strong\u003E \u2014 stop the running site before rebuilding a plugin.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EStarting over\u003C/strong\u003E \u2014 delete \u003Ccode\u003EApp_Data/Settings.cfg\u003C/code\u003E and restart; the wizard appears again. Use a new, empty database.\u003C/li\u003E\n\u003C/ul\u003E\n\n\u003Ch2 id=\u0022related\u0022\u003ERelated\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\u0022/getting-started-installation-wizard\u0022\u003EThe installation wizard\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\u0022/getting-started-upgrading\u0022\u003EUpgrading to a new version\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E","ParentCategoryId":"6abdec6c83d2816248229ea1","SeName":"getting-started-installing","MetaKeywords":null,"MetaDescription":"Install GrandNode with the Docker image, from a GitHub release package or from source with dotnet build and dotnet run, and host it on Linux.","MetaTitle":null,"AllowComments":false,"Captcha":{"ReCaptchaChallengeField":null,"ReCaptchaResponseField":null,"ReCaptchaResponseValue":null,"ReCaptchaResponse":null},"RelatedArticles":[],"CategoryBreadcrumb":[{"Name":"Getting started","Description":null,"IsCurrent":false,"Children":null,"Parent":null,"SeName":"docs-getting-started","Id":"6abdec6c83d2816248229ea1","UserFields":[]}],"AddNewComment":{"CommentText":null,"DisplayCaptcha":false,"Id":null,"UserFields":[]},"Comments":[],"Id":"6abdec6c83d2816248229ea7","UserFields":[]}