Compare commits

...

3 Commits

19 changed files with 524 additions and 198 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
repo-to*
build/

View File

@ -0,0 +1,16 @@
# Details: https://github.com/kirill-markin/repo-to-text
# Syntax: gitignore rules
# Ignore files and directories for all sections from gitignore file
# Default: True
gitignore-import-and-ignore: True
# Ignore files and directories for tree
# and "Contents of ..." sections
ignore-tree-and-content:
- ".repo-to-text-settings.yaml"
# Ignore files and directories for "Contents of ..." section
ignore-content:
- "README.md"
- "LICENSE"

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,21 +1,89 @@
# NixOS Proxmox LXC Container Configuration # NixOS Proxmox LXC Container Configuration
Quickly configure a NixOS LXC container in Proxmox with custom IP address and SSH key settings. A comprehensive toolkit for managing NixOS containers in Proxmox VE. This repository provides automated configuration and management tools for NixOS LXC containers.
## One-Line Installation ## Features
- Automated container detection and configuration
- Optimized NixOS settings for LXC containers
- Automatic system upgrades and maintenance
- Proper terminal and shell configuration
- DHCP networking configuration
- Secure SSH access setup
- Nix Flakes support
- Garbage collection and store optimization
## Quick Installation
```bash ```bash
curl -sSf https://git.jeirslab.xyz/jeirmeister/NixOS-PVE-LXC/raw/branch/main/config-lxc.sh | bash curl -sSf https://git.jeirslab.xyz/jeirmeister/NixOS-PVE-Deployment-Util/raw/branch/main/setup.sh | bash
``` ```
The script will: ## What It Does
- Prompt for container ID (100-999)
- Request your SSH public key
- Ask for IP address and gateway
- Configure the container with these settings
- Apply the configuration automatically
**Note**: Always verify scripts before running them with curl. You can inspect the source at the repository first. The installation script will:
1. Install required dependencies (git)
2. Clone/update the configuration repository
3. Detect available NixOS containers
4. Apply optimized configuration settings
5. Configure proper LXC terminal access
6. Set up system maintenance tasks
Citations: ## Manual Installation
[1] https://git.jeirslab.xyz/jeirmeister/NixOS-PVE-LXC/raw/branch/main/configuration.nix
If you prefer to inspect the code first:
```bash
git clone https://git.jeirslab.xyz/jeirmeister/NixOS-PVE-LXC.git
cd NixOS-PVE-LXC
./setup.sh
```
## Directory Structure
```
.
├── nix-config/ # NixOS configuration files
│ ├── configuration.nix # Main configuration
│ ├── lxc.nix # LXC-specific settings
│ ├── network.nix # Network configuration
│ └── users.nix # User and SSH settings
└── scripts/ # Utility scripts
├── list-lxcs.sh # Container detection
├── mount-nixos-config.sh # Configuration deployment
├── rebuild-nixos.sh # System rebuild
└── setup-lxc-terminal.sh # Terminal setup
```
## Features in Detail
### System Optimization
- Automatic garbage collection
- Store optimization
- Weekly system updates
- Nix Flakes support
### Security
- SSH-based access
- No root login
- Wheel group for sudo access
- Secure default configurations
### Networking
- DHCP configuration
- IPv6 support
- Proper network interface setup
## Requirements
- Proxmox VE 7.0 or later
- NixOS LXC container(s)
- Root access to Proxmox host
## Contributing
Contributions are welcome! Please feel free to submit pull requests or create issues for bugs and feature requests.
## Note
Always review scripts before running them with curl. You can inspect all source code at the repository.

40
TODO.md Normal file
View File

@ -0,0 +1,40 @@
## Roadmap & TODOs
### Planned Features
- **Automated Deployment**
- Deploy LXC containers with user-defined variables (hostname, cores, memory, storage)
- Deploy VMs using customizable templates and configurations
- Automated latest NixOS build fetching and deployment
- Host SSH key integration for secure access
- **Configuration Management**
- Support for custom NixOS configuration overlays
- Template-based configuration system
- LXC-specific optimization notes and best practices
### Integration Goals
- Pending compatibility and integration into [Proxmox Community Scripts](https://community-scripts.github.io/ProxmoxVE/)
- Support for custom configuration files with minimal LXC requirements
### Development Notes
```bash
# LXC Deployment Variables
- Container ID
- Resource allocation (CPU, RAM, Storage)
- Network configuration
- User access and SSH keys
# VM Deployment Variables
- VM ID
- Hardware configuration
- Boot options
- Network settings
```
### Current Limitations
- Manual container creation required
- Limited template customization
- No automated SSH key management
This roadmap will be updated as development progresses.

View File

@ -1,122 +0,0 @@
#!/bin/bash
set -e
# Function to display usage
usage() {
echo "Usage: $0 <container_id> --ssh-key <ssh_key> --ip <ip_address> --gateway <gateway> --user <username>"
echo " <container_id>: ID of the container (100-999)"
echo " --ssh-key: SSH public key for the user"
echo " --ip: IP address for the container"
echo " --gateway: Gateway IP address"
echo " --user: Username for the admin user (default: admin)"
exit 1
}
# Function to validate IP address format
validate_ip() {
if [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
return 0
fi
return 1
}
# Parse command-line arguments
CTID=$1
shift
while [[ $# -gt 0 ]]; do
case $1 in
--ssh-key) SSH_KEY="$2"; shift 2 ;;
--ip) IP_ADDRESS="$2"; shift 2 ;;
--gateway) GATEWAY="$2"; shift 2 ;;
--user) USERNAME="$2"; shift 2 ;;
*) echo "Unknown option: $1"; usage ;;
esac
done
# Validate inputs
[[ ! $CTID =~ ^[1-9][0-9]{2}$ ]] && { echo "Error: Invalid container ID"; usage; }
[[ -z $SSH_KEY ]] && { echo "Error: SSH key is required"; usage; }
[[ -z $IP_ADDRESS ]] && { echo "Error: IP address is required"; usage; }
[[ -z $GATEWAY ]] && { echo "Error: Gateway is required"; usage; }
validate_ip "$IP_ADDRESS" || { echo "Error: Invalid IP address"; usage; }
validate_ip "$GATEWAY" || { echo "Error: Invalid gateway"; usage; }
USERNAME=${USERNAME:-admin}
# Function to generate NixOS configuration
generate_nixos_config() {
cat << EOF
{ modulesPath, config, pkgs, ... }:
{
imports = [ "\${modulesPath}/virtualisation/lxc-container.nix" ];
boot.isContainer = true;
systemd.suppressedSystemUnits = [
"dev-mqueue.mount"
"sys-kernel-debug.mount"
"sys-fs-fuse-connections.mount"
];
environment.systemPackages = with pkgs; [ openssh binutils man git ];
users.users.${USERNAME} = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [ "${SSH_KEY}" ];
};
security.sudo.wheelNeedsPassword = false;
programs.nix-ld.enable = true;
services.openssh = {
enable = true;
settings = {
AllowUsers = ["${USERNAME}"];
PasswordAuthentication = false;
PermitRootLogin = "no";
};
};
networking = {
dhcpcd.enable = false;
useDHCP = false;
useHostResolvConf = false;
defaultGateway = "${GATEWAY}";
nameservers = [ "8.8.8.8" "8.8.4.4" ];
interfaces.eth0.ipv4.addresses = [{
address = "${IP_ADDRESS}";
prefixLength = 24;
}];
};
system.stateVersion = "24.05";
}
EOF
}
# Main execution
if ! pct status "$CTID" >/dev/null 2>&1; then
echo "Error: Container $CTID does not exist"
exit 1
fi
CONFIG_CONTENT=$(generate_nixos_config)
pct start ${CTID}
sleep 10
pct enter ${CTID} << EOF
/run/current-system/sw/bin/bash << 'INNEREOF'
export PATH=/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin:\$PATH
source /etc/profile
mkdir -p /etc/nixos
cat > /etc/nixos/configuration.nix << 'CONFIGEOF'
${CONFIG_CONTENT}
CONFIGEOF
nixos-rebuild switch
INNEREOF
EOF
echo "Configuration applied successfully!"

View File

@ -1,64 +0,0 @@
{ modulesPath, config, pkgs, ... }:
{
imports =
[
# Default path for lxc/lxd configuration
"${modulesPath}/virtualisation/lxc-container.nix"
];
boot.isContainer = true;
systemd.suppressedSystemUnits = [
"dev-mqueue.mount"
"sys-kernel-debug.mount"
"sys-fs-fuse-connections.mount"
];
# Essential packages
environment.systemPackages = with pkgs; [
openssh
binutils
man
git
];
# Administrative sudo user
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # wheel group is sudo access
};
security.sudo.wheelNeedsPassword = true;
# Facilitates access via VS Code Remote Explorer
programs.nix-ld.enable = true;
# Enable password-based SSH login for admin user
services.openssh = {
enable = true;
settings = {
AllowUsers = ["admin"]; # everyone
PasswordAuthentication = true;
PermitRootLogin = "no";
};
};
networking = {
dhcpcd.enable = false;
useDHCP = false;
useHostResolvConf = false;
};
systemd.network = {
enable = true;
networks."50-eth0" = {
matchConfig.Name = "eth0";
networkConfig = {
DHCP = "ipv4";
IPv6AcceptRA = true;
};
linkConfig.RequiredForOnline = "routable";
};
};
system.stateVersion = "24.05"; # Did you read the comment?
}

View File

@ -0,0 +1,42 @@
{ modulesPath, config, pkgs, ... }:
{
imports = [
./lxc.nix
./users.nix
./network.nix
];
# Nix settings
nix = {
settings = {
auto-optimise-store = true;
experimental-features = [ "nix-command" "flakes" ];
allowed-users = [ "@wheel" ];
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# Set NIX_PATH
nix.nixPath = [
"nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
"nixos-config=/etc/nixos/configuration.nix"
"/nix/var/nix/profiles/per-user/root/channels"
];
# Auto upgrades
system.autoUpgrade = {
enable = true;
dates = "04:00";
randomizedDelaySec = "45min";
persistent = true;
};
system.stateVersion = "24.05";
}

23
nix-config/lxc.nix Normal file
View File

@ -0,0 +1,23 @@
{ modulesPath, config, pkgs, ... }:
{
imports = [
"${modulesPath}/virtualisation/lxc-container.nix"
];
boot.isContainer = true;
systemd.suppressedSystemUnits = [
"dev-mqueue.mount"
"sys-kernel-debug.mount"
"sys-fs-fuse-connections.mount"
];
environment.systemPackages = with pkgs; [
openssh
binutils
man
git
];
programs.nix-ld.enable = true;
}

20
nix-config/network.nix Normal file
View File

@ -0,0 +1,20 @@
{ config, pkgs, ... }:
{
networking = {
dhcpcd.enable = false;
useDHCP = false;
useHostResolvConf = false;
};
systemd.network = {
enable = true;
networks."50-eth0" = {
matchConfig.Name = "eth0";
networkConfig = {
DHCP = "ipv4";
IPv6AcceptRA = true;
};
linkConfig.RequiredForOnline = "routable";
};
};
}

View File

@ -0,0 +1,20 @@
{ modulesPath, config, pkgs, ... }:
{
# Administrative sudo user
users.users.admin = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # wheel group is sudo access
};
# Enable password-based SSH login for admin user
services.openssh = {
enable = true;
settings = {
AllowUsers = ["admin"]; # everyone
PasswordAuthentication = true;
PermitRootLogin = "no";
};
};
}

18
nix-config/users.nix Normal file
View File

@ -0,0 +1,18 @@
{ config, pkgs, ... }:
{
users.users.nixos = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
security.sudo.wheelNeedsPassword = true;
services.openssh = {
enable = true;
settings = {
AllowUsers = ["nixos"];
PasswordAuthentication = true;
PermitRootLogin = "no";
};
};
}

25
scripts/get-latest.sh Normal file
View File

@ -0,0 +1,25 @@
#!/bin/bash
IMAGE_TYPE="$1"
BASE_URL="https://hydra.nixos.org/job/nixos/release-24.11/nixos"
DOWNLOAD_DIR="./build"
if [ "$IMAGE_TYPE" = "VM" ]; then
DOWNLOAD_URL="${BASE_URL}.proxmoxImage.x86_64-linux/latest/download/1"
OUTPUT_FILE="${DOWNLOAD_DIR}/nixos_proxmox_vm.vma.zst"
elif [ "$IMAGE_TYPE" = "LXC" ]; then
DOWNLOAD_URL="${BASE_URL}.proxmoxLXC.x86_64-linux/latest/download/1"
OUTPUT_FILE="${DOWNLOAD_DIR}/nixos_proxmox_lxc.tar.xz"
else
echo "Error: Invalid image type. Must be 'VM' or 'LXC'" >&2
exit 1
fi
wget -q --show-progress -O "$OUTPUT_FILE" "$DOWNLOAD_URL"
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
echo "Error: Download failed" >&2
rm -f "$OUTPUT_FILE"
exit $EXIT_CODE
fi

49
scripts/list-lxcs.sh Normal file
View File

@ -0,0 +1,49 @@
#!/bin/bash
# ANSI color codes
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
# Array to store valid CTIDs
declare -a valid_ctids
echo -e "${BLUE}Available NixOS Containers:${NC}"
printf "%-8s %s\n" "VMID" "Name"
echo "----------------"
# Populate the list and store valid CTIDs
for conf in /etc/pve/lxc/*.conf; do
if grep -q "^ostype: nixos" "$conf"; then
vmid=$(basename "$conf" .conf)
name=$(grep "^hostname:" "$conf" | cut -d' ' -f2)
printf "%-8s %s\n" "$vmid" "$name"
valid_ctids+=("$vmid")
fi
done
if [ ${#valid_ctids[@]} -eq 0 ]; then
echo -e "${RED}No NixOS containers found!${NC}" >&2
exit 1
fi
# Ask for user input
echo -e "\nEnter the CTID of the container you want to configure:"
read -r selected_ctid
# Validate input
valid=0
for ctid in "${valid_ctids[@]}"; do
if [ "$ctid" = "$selected_ctid" ]; then
valid=1
break
fi
done
if [ $valid -eq 0 ]; then
echo -e "${RED}Error: Invalid CTID selected!${NC}" >&2
exit 1
fi
# Output the selected CTID for use in other scripts
echo "$selected_ctid"

View File

@ -0,0 +1,39 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Usage: $0 <container_id>"
exit 1
fi
CTID="$1"
CONFIG_FILE="/etc/pve/lxc/${CTID}.conf"
MOUNT_POINT="/root/nixos-config-${CTID}"
NIX_CONFIG_DIR="./nix-config"
if [ ! -d "$NIX_CONFIG_DIR" ]; then
echo "Error: nix-config directory not found"
exit 1
fi
# Parse container config and mount
echo "Parsing container configuration..."
ROOTFS_LINE=$(grep "^rootfs:" "$CONFIG_FILE")
VOLUME_NAME=$(echo "$ROOTFS_LINE" | sed 's/rootfs: local-lvm:\([^,]*\).*/\1/')
DEVICE_PATH="/dev/pve/${VOLUME_NAME}"
echo "Creating mount point..."
mkdir -p "$MOUNT_POINT"
echo "Mounting container filesystem..."
mount "$DEVICE_PATH" "$MOUNT_POINT"
echo "Copying NixOS configuration..."
mkdir -p "${MOUNT_POINT}/etc/nixos"
cp -r ${NIX_CONFIG_DIR}/* "${MOUNT_POINT}/etc/nixos/"
echo "Unmounting container filesystem..."
umount "$MOUNT_POINT"
rmdir "$MOUNT_POINT"
echo "Configuration files copied successfully"

10
scripts/post-deploy.sh Normal file
View File

@ -0,0 +1,10 @@
#!/bin/bash
# ANSI color codes
GREEN='\033[0;32m'
NC='\033[0m' # No Color
# Get primary IP address (excluding docker/vm interfaces)
IP_ADDRESS=$(ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '^127\.' | head -n 1)
echo -e "${HOSTNAME} is now deployed at ${GREEN}${IP_ADDRESS}${NC}"

17
scripts/rebuild-nixos.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Usage: $0 <container_id>"
exit 1
fi
CTID="$1"
echo "Updating channels..."
pct exec ${CTID} -- nix-channel --update
echo "Rebuilding NixOS configuration..."
pct exec ${CTID} -- nixos-rebuild switch -I nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos -I nixos-config=/etc/nixos/configuration.nix
echo "NixOS rebuild completed successfully"

View File

@ -0,0 +1,37 @@
#!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Usage: $0 <container_id>"
exit 1
fi
CTID="$1"
# Function to add or update line in config file
update_config_line() {
local file="$1"
local search="$2"
local replace="$3"
if [ -f "$file" ]; then
if ! grep -q "^${search}" "$file"; then
echo "${replace}" >> "$file"
else
sed -i "s|^${search}.*|${replace}|" "$file"
fi
fi
}
# Update Proxmox LXC config
PVE_CONFIG="/etc/pve/lxc/${CTID}.conf"
update_config_line "$PVE_CONFIG" "lxc.init_cmd:" "lxc.init_cmd: /run/current-system/sw/bin/bash"
update_config_line "$PVE_CONFIG" "cmode:" "cmode: shell"
# Update LXC system config
LXC_CONFIG="/var/lib/lxc/${CTID}/config"
update_config_line "$LXC_CONFIG" "lxc.init.cmd" "lxc.init.cmd = /run/current-system/sw/bin/bash"
update_config_line "$LXC_CONFIG" "lxc.environment = TERM" "lxc.environment = TERM=linux"
update_config_line "$LXC_CONFIG" "lxc.environment = PATH" "lxc.environment = PATH=/run/current-system/sw/bin"
echo "LXC terminal configuration updated successfully"

65
setup.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
set -e
# ANSI color codes
BLUE='\033[0;34m'
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
# Check if running as root
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
# Check and install git if needed
if ! command -v git >/dev/null 2>&1; then
echo "Installing git..."
nix-env -i git
fi
REPO_DIR="/root/.nixos-utils"
# Clone or update repository
if [ -d "$REPO_DIR" ]; then
echo "Updating existing repository..."
cd "$REPO_DIR"
git pull
else
echo "Cloning repository..."
git clone https://git.jeirslab.xyz/jeirmeister/NixOS-PVE-LXC.git "$REPO_DIR"
cd "$REPO_DIR"
fi
# Make scripts executable
echo "Making scripts executable..."
find ./scripts -name "*.sh" -execdir chmod u+x {} +
# Get CTID from list-lxcs.sh
echo -e "${BLUE}Detecting NixOS containers...${NC}"
CTID=$(./scripts/list-lxcs.sh)
if [ -z "$CTID" ]; then
echo -e "${RED}No container ID was selected${NC}"
exit 1
fi
echo -e "${GREEN}Selected container: $CTID${NC}"
# Execute configuration steps in sequence
echo -e "\nConfiguring NixOS container $CTID..."
echo "Step 1: Setting up LXC terminal..."
./scripts/setup-lxc-terminal.sh "$CTID"
echo "Step 2: Mounting and copying NixOS configuration..."
./scripts/mount-nixos-config.sh "$CTID"
echo "Step 3: Rebuilding NixOS configuration..."
./scripts/rebuild-nixos.sh "$CTID"
echo "Step 4: Running post-deployment tasks..."
./scripts/post-deploy.sh
echo -e "${GREEN}NixOS container $CTID has been configured successfully!${NC}"