How to run a docker container declaratively on nixos server? - linux

How do I run a docker container declaratively on nixos server ? I am trying to run whoogle on a nix server and I don't wish to manually restart the whoogle container everytime I restart the server.

After bit of guidance from the r/nixos community settled with this.
{ config, pkgs, ... }:
let
host = "mydomain";
in
{
virtualisation = {
podman = {
enable = true;
dockerCompat = true;
};
oci-containers = {
backend = "podman";
containers.whoogle-search = {
image = "benbusby/whoogle-search";
autoStart = true;
ports = [ "8080:5000" ]; #server locahost : docker localhost
};
};
};
services.nginx.virtualHosts = {
"search.${host}" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://localhost:8080";
};
};
}

Use --restart always with docker command at initial start
enable docker service to start at boot
And your container will start at boot

Related

How to check whether a Node.js service is running - in my case Azurite emulator?

I am developing a C# application that should run in Azure. I want to use the Azurite emulator to test it locally. What I want to achieve is: Have my tests detect whether Azurite is running and abort quickly with a nice error message if it is not running.
Apparently Azurite runs on Node.js.
With the old Microsoft Azure Storage Emulator, I can check it like this:
public static class AzureStorageEmulatorDetector
{
public static bool IsRunning()
{
const string exePath = #"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe";
if (!File.Exists(exePath))
return false;
var processStartInfo = new ProcessStartInfo {FileName = exePath, Arguments = "status", RedirectStandardOutput = true};
var process = new Process {StartInfo = processStartInfo};
process.Start();
process.WaitForExit();
var processOutput = process.StandardOutput.ReadToEnd();
return processOutput.Contains("IsRunning: True");
}
}
I want to accomplish something similar with Azurite.
I have installed Azurite like this:
npm install -g azurite
I run it like this:
azurite --silent --location C:\temp\Azurite --debug c:\temp\Azurite\debug.log
I notice that the Azurite command-line application has no parameter that tells me whether it is already running. And when I start Azurite from the console I don't see any process or service in Task Explorer called anything like "azurite". So I don't know what process I'm supposed to check for.
EDIT: Apparently Azurite runs on Node.js. There is indeed a process called node.exe running, but that's not a sufficient condition. Can I query my running Node.js instance and get it to tell me what it is doing?
I am on Windows.
Does anyone know?
Inspired by the comment by Ivan Yang and this answer I did this:
private static bool IsAzuriteRunning()
{
// If Azurite is running, it will run on localhost and listen on port 10000 and/or 10001.
IPAddress expectedIp = new(new byte[] {127, 0, 0, 1});
var expectedPorts = new[] {10000, 10001};
var activeTcpListeners = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
var relevantListeners = activeTcpListeners.Where(t =>
expectedPorts.Contains(t.Port) &&
t.Address.Equals(expectedIp))
.ToList();
return relevantListeners.Any();
}
EDIT: Alternatively, check out this thread on their GitHub for other possibilities: https://github.com/Azure/Azurite/issues/734

Azure Linux App Service with .Net Core Stack. Unable to use NodeJS

I am hosting a .NET Core Application on MS Azure (on a Linux Service Plan) and I want to run some NodeJS code in the .NET Core Application. I did this a while ago on a Windows Service Plan, there it was working. Now I am trying with a Linux Plan and it is not working.
First I was trying to use "Jering.Javascript.NodeJS" and then also "INodeServices" from Microsoft (which is obsolete). But "node" was not found. I also tried to start directly a Process (Code below), but also not working. "node" is not found.
var proc = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "node",
Arguments = " -v",
RedirectStandardOutput = true
}
};
result += "RUN: " + proc.StartInfo.FileName;
proc.Start();
var reader = proc.StandardOutput;
NodeJS is installed on the server and also the command works there but it seems that the .NET Core app is hosted as docker and does not have any access outside to run NodeJS. Image
I found a useful information here.
The problem is that Node is not present in the container so it is
necessary to have a script to install and start it before starting the
app itself.
Reproduce:
Here is my script:
//using System.Diagnostics;
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = "bash";
//startinfo.FileName = "/etc/opt/nodejs/14.15.0/bin/node"; //it's no use even node package located here.
Process process = new Process();
process.StartInfo = startinfo;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
//install and start nodejs
process.StandardInput.WriteLine("apt-get install curl");
process.StandardInput.WriteLine("curl -sL https://deb.nodesource.com/setup_12.x | bash");
process.StandardInput.WriteLine("apt-get install -y nodejs");
//Run "node -v"
process.StandardInput.WriteLine("node -v");
string line = string.Empty;
while (!process.StandardOutput.EndOfStream)
{
line = process.StandardOutput.ReadLine();
_logger.LogInformation(line);
}
process.WaitForExit();
return string.Empty;
It works on my .net Core app based on Linux.
I think I found a better solution ;)
In an app service you can mount a storage. In my case I mounted a storage, which contains the nodeJS lib.
Azure Portal Screenshot
Now i can execute the following code:
string result = "";
var proc = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "/externallibs/node/bin/node",
Arguments = " -v",
RedirectStandardOutput = true
}
};
result += "RUN: " + proc.StartInfo.FileName;
proc.Start();
var reader = proc.StandardOutput;
return result + reader.ReadToEnd();
You can create on azure portal an environment var named POST_BUILD_COMMAND with a command to fix your environment path.
Linux Service Plans runs on Oryx which is documented here
POST_BUILD_COMMAND=PATH=/usr/bin/node:$PATH

How to access container id in NodeJs application in host network mode

I am trying to get a docker container's Id when network=host settings is enabled but instead of getting the containerId I am getting the host instance name. But, in case my network=host is not passed in the command it gives me the containerId as expected.
In short:
Case 1- I run my container with command – docker run --network="host" -d -it myservice:1.0
const os = require("os");
console.log(os.hostname()) /// prints **docker-desktop**
Case 2- I run my container with command – docker run -d -it myservice:1.0
const os = require("os");
console.log(os.hostname()) /// prints **67db4w32k112** as expected
Is there a way I can get the same output i.e 67db4w32k112 in case 1 as well?
From looking at this thread you can probably do something like below which will read the /proc/1/cpuset file inside the container. This file has the current container ID, the contents look like:
/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
This will be more reliable in your case than using os.hostname() since it works both with and without the --newtwork="host"flag on the docker run command.
fs = require('fs')
fs.readFile('/proc/1/cpuset', 'utf8', function(err, data) {
if (err) {
return console.log(err);
}
let containerID = data.replace("/docker/", "");
console.log(containerID);
});
Try to use a helper package such as docker-container-id
Add the dependency in your package.json
npm install --save docker-container-id
Here's an example:
const getId = require('docker-container-id');
async function() {
console.log("I'm in container:", await getId());
}
npmjs reference

Enable wireless, no X, on nixos

What is the configuration I would use to enable my wireless adapter WITHOUT having any X Server/Desktop installed. The install is simply a terminal install. Also I want to specify a static IP address for the machine. If someone could share the nixos configuration to achieve that, it would be appreciated.
This code will do it:
networking = {
interfaces.wlp1s0.ip4 = [ { address = "192.168.0.150"; prefixLength = 24; } ];
defaultGateway = "192.168.0.1";
nameservers = [ "8.8.8.8" ];
wireless = {
enable = true;
interfaces = ["wlp1s0"];
userControlled.enable = true;
userControlled.group = "wheel";
networks = {
"1529-upstairs-2.4" = {
psk = "abc7654321";
};
};
};
hostName = "delldesk";
};
environment.systemPackages = with pkgs; [
dhcpcd wpa_supplicant
];
my wireless device is: wlp1s0.
I have a network called: 1529-upstairs-2.4
The password to that WIFI is: abc7654321

How to add custom services in Nixos

using nixops one can easily configure services like:
{
network.description = "Web server";
webserver = { config, pkgs, ... }:
{
services.mysql = {
enable = true;
package = pkgs.mysql51;
};
but i want to extend services. for example by using override as done for pkgs below:
let
myfoo = callPackage ...
in
pkgs = pkgs.override {
overrides = self: super: {
myfoo-core = myfoo;
};
}
question
how to do that for services?
Adding a service requires that you first write a service definition for your service. That is, a nix file that declares the options of your service and provides an implementation.
Let's say our service is called foo, then we write a service definition for it an save it as the file foo.nix:
{ config, lib, pkgs, ... }:
with lib; # use the functions from lib, such as mkIf
let
# the values of the options set for the service by the user of the service
foocfg = config.services.foo;
in {
##### interface. here we define the options that users of our service can specify
options = {
# the options for our service will be located under services.foo
services.foo = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable foo.
'';
};
barOption = {
type = types.str;
default = "qux";
description = ''
The bar option for foo.
'';
};
};
};
##### implementation
config = mkIf foocfg.enable { # only apply the following settings if enabled
# here all options that can be specified in configuration.nix may be used
# configure systemd services
# add system users
# write config files, just as an example here:
environment.etc."foo-bar" = {
text = foocfg.bar; # we can use values of options for this service here
};
};
For example, for Hydra, this file can be found here: https://github.com/NixOS/hydra/blob/dd32033657fc7d6a755c2feae1714148ee43fc7e/hydra-module.nix.
After having written the service definition, we can use it our main configuration like this:
{
network.description = "Web server";
webserver = { config, pkgs, ... }: {
imports = [ ./foo.nix ]; # import our service
services.mysql = {
enable = true;
package = pkgs.mysql51;
};
services.foo = {
enable = true;
bar = "hello nixos modules!";
};
};
}
Disclaimer: there might be some typos in this, I have not tested it.
according to aszlig, we can do this:
configuration.nix
{ config, lib, ... }:
{
disabledModules = [ "services/monitoring/nagios.nix" ];
options.services.nagios.enable = lib.mkOption {
# Make sure that this option type conflicts with the one in
# the original NixOS module for illustration purposes.
type = lib.types.str;
default = "of course";
description = "Really enable nagios?";
};
config = lib.mkIf (config.services.nagios.enable == "of course") {
systemd.services.nagios = {
description = "my own shiny nagios service...";
};
};
}
evaluate it
$ nix-instantiate --eval '<nixpkgs/nixos>' --arg configuration ./test-disable.nix -A config.systemd.services.nagios.description
"my own shiny nagios service..."

versus without disabledModules:
$ nix-instantiate --eval '<nixpkgs/nixos>' --arg configuration ./test-disable.nix -A config.systemd.services.nagios.description
error: The option `services.nagios.enable' in `/home/aszlig/test-disable.nix' is already declared in `/nix/var/nix/profiles/per-user/root/channels/vuizvui/nixpkgs/nixos/modules/services/monitoring/nagios.nix'.
(use '--show-trace' to show detailed location information)

Resources