added stuff
This commit is contained in:
parent
e8d9044d2b
commit
9d0ebdfbd0
907 changed files with 70990 additions and 0 deletions
145
nyx/docs/notes/2023-05-21-packaging-nextjs-webapps.md
Normal file
145
nyx/docs/notes/2023-05-21-packaging-nextjs-webapps.md
Normal file
|
@ -0,0 +1,145 @@
|
|||
# Notes for 21st of June, 2023
|
||||
|
||||
Recenty I have had to go through the misfortune of hosting some websites
|
||||
written with _NextJS_ on my VPS running NixOS, this note entry shall document
|
||||
my experience and the "easy" path I have chosen.
|
||||
|
||||
## Packaging
|
||||
|
||||
The websites I hosted were of two variety: those statically exported, and
|
||||
those that cannot be statically exported.
|
||||
|
||||
### Statically Exported Webapps
|
||||
|
||||
Statically exported ones are easy to package, because it is a matter of
|
||||
running `npm build` (or whatever your build script is) with the following
|
||||
NextJS settings
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
module.exports = {
|
||||
distDir: "dist", // an artitrary path for your export
|
||||
output: "export",
|
||||
};
|
||||
```
|
||||
|
||||
This will export a static website with a bunch of html files that you can
|
||||
then serve with nodePackages.serve or a webserver like nginx or apache.
|
||||
And that is the end of your worries for a statically exported website! No
|
||||
headache, just write a simple derivation, such as the one below
|
||||
|
||||
```nix
|
||||
# default.nix
|
||||
{
|
||||
buildNpmPackage,
|
||||
pkg-config,
|
||||
python3,
|
||||
...
|
||||
}:
|
||||
buildNpmPackage {
|
||||
pname = "your-website";
|
||||
version = "0.1";
|
||||
|
||||
src = ./.;
|
||||
# needs to be updated everytime you update npm dependencies
|
||||
npmDepsHash = "sha256-some-hash";
|
||||
# some npm packages may need to be built from source, because nodejs is a *terrible* ecosystem
|
||||
nativeBuildInputs = [pkg-config python3];
|
||||
|
||||
# move exported website to $out
|
||||
postInstall = ''
|
||||
cp -rf dist/* $out
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
and serve its path with a simple tool after building the derivation, I find
|
||||
nginx to be awfully convenient for doing so, but you may choose caddy if you
|
||||
prefer.
|
||||
|
||||
### Webapps that cannot be statically exported
|
||||
|
||||
If your website depends on API routes for some reasons, then Next will not
|
||||
allow you to do static export. Which means you need to run `next start` in
|
||||
some shape or form. While a systemd service is certainly a way of doing it
|
||||
(one that I do not recommend), a oci container works as well if not better.
|
||||
|
||||
You can write a "simple" docker image for your oci container to use, such as
|
||||
the one below
|
||||
|
||||
```nix
|
||||
# dockerImage.nix
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
dockerImage = pkgs.dockerTools.buildImage {
|
||||
config = {
|
||||
WorkingDir = "/your-website";
|
||||
Cmd = ["npm" "run" "serve"];
|
||||
};
|
||||
|
||||
name = "your-website";
|
||||
tag = "latest";
|
||||
|
||||
fromImage = pkgs.dockerTools.buildImage {
|
||||
name = "node";
|
||||
tag = "18-alpine";
|
||||
};
|
||||
|
||||
copyToRoot = pkgs.buildEnv {
|
||||
name = "image-root";
|
||||
|
||||
paths = with pkgs; [
|
||||
# this package is called from a flake.nix alongside the derivation for the website
|
||||
inputs.self.packages.${pkgs.system}.your-website
|
||||
nodejs
|
||||
bash
|
||||
];
|
||||
|
||||
pathsToLink = [
|
||||
"/bin"
|
||||
"/your-website"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then, configure oci-containers module option to pick up the Docker image that
|
||||
you have built. This is a simplified version of my VPS' container setup.
|
||||
An example can be found in my [server module](https://github.com/NotAShelf/nyx/blob/a9e129663ac91302f2fd935351a71cbbd2832f64/modules/core/roles/server/system/services/mkm.nix)
|
||||
|
||||
```nix
|
||||
virtualisation.oci-containers = {
|
||||
backend = "podman";
|
||||
containers = {
|
||||
"website-container" = {
|
||||
autoStart = true;
|
||||
ports = [
|
||||
"3000:3000" # bind container's port 3000 to the outside port 3000 for NextJS
|
||||
];
|
||||
|
||||
extraOptions = ["--network=host"];
|
||||
|
||||
image = "your-website";
|
||||
imageFile = inputs.website-flake.packages.${pkgs.system}.dockerImage;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
After a rebuild, your system will provision the container and start it on
|
||||
port **3000**. You can access it with `your-server-ip:3000` in your
|
||||
browser, and even configure nginx to set up a reverse proxy to assign
|
||||
your domain.
|
||||
|
||||
```conf
|
||||
"example.com" = {
|
||||
locations."/".proxyPass = "http://127.0.0.1:3000";
|
||||
};
|
||||
```
|
||||
|
||||
This will assign your domain to your webserver, and allow outside
|
||||
visitors to view your "awesome" NextJS webapp.
|
Loading…
Add table
Add a link
Reference in a new issue