11 How to create a new LXC
Mathieu Broillet edited this page 2023-06-23 09:44:30 +00:00

To create a new LXC you need to create a folder in your repo at <repo>/lxc/<id of lxc>/ and then inside it add a config.yml file.

Here is an example config file with all possible settings :

config.yml
lxc_hostname: <hostname of the lxc>

os:
  name: <alpine | archlinux | centos | debian | devuan | fedora | gentoo | nixos | opensuse | ubuntu>
  release: <depends on os>

resources:
  cpu: <amount of cpu cores>
  memory: <megabytes of ram>
  swap: <megabytes of swap>
  disk: <gigabytes of storage>
  storage: <name of proxmox storage>

network:
  bridge: <bridge>
  firewall: <1|0>
  gw: <GatewayIPv4>
  gw6: <GatewayIPv6>
  hwaddr: <XX:XX:XX:XX:XX:XX>
  ip: <IPv4/CIDR|dhcp|manual>
  ip6: <IPv6/CIDR|auto|dhcp|manual>
  link_down: <1|0>
  mtu: <integer>
  rate: <mbps>
  tag: <integer>
  trunks: <vlanid[;vlanid...]>

options:
  privileged: <is the lxc privileged>
  start_on_boot: <should the lxc start at boot>
  startup_order: <order of startup/shutdown>
  password: <password of root user in lxc>
  tags: [ <optionals-tags in the pve ui> ]

features:
  force_rw_sys: <1|0>
  fuse: <1|0>
  keyctl: <1|0>
  mknod: <1|0>
  mount: <fstype;fstype;...>
  nesting: <1|0>

creation:
  conditions:
    <conditions go here, see next chapters>

  steps:
    <steps go here, see next chapters>
deploy:
  conditions:
    <conditions go here, see next chapters>

  steps:
    <steps go here, see next chapters>

For the network and features sections, you can look at the Proxmox documentation for the available options and the format.

Creation/Deploy process

Both the creation and the deployment processes are divided in two parts : conditions and steps.

Conditions

The conditions are mostly used during the creation process to check if your program has already been installed or not.
For example, if your LXC deploys a vaultwarden instance, then your creation condition will be to check if the program vaultwarden is installed or not. If it is then it will run the deploy (update) steps and won't redo the installation.

You can define global condition for the creation and the deploy process, and you can also define specific conditions for each individual step.

# config.yml
creation:
  # Global conditions
  conditions:
    programs:
      - <name of program>
    files:
      - "<path of file in lxc>"
    folders:
      - "<path of folder in  lxc>"

  steps:
    - type: <script>
      path: "<path to script>"
      # Step specific condition(s)
      conditions:
        programs:
          - <name of program>

Types of conditions :

Programs

Checks if a program is installed or not

program: <name of program>
programs:
  - <name of program 1>
  - <name of program 2>

You can use either program or programs, they do the same thing

Files

Checks if a file exist or not

file: <name of program>
files:
  - <path to file 1>
  - <path to file 2>

You can use either file or files, they do the same thing

Folders

Checks if a folder exist or not

folder: <name of program>
folders:
  - <path to folder 1>
  - <path to folder 2>

You can use either folder or folders, they do the same thing

Commands

Checks if a command return the expected value

command: [ <command to run>, <value expected> ]
commands:
  - [ <command to run 1>, <value expected 1> ]
  - [ <command to run 2>, <value expected 2> ]

You can use either command or commands, they do the same thing

Docker containers

Checks if a docker container exist or not

docker: <name of docker container>
docker:
  - <name of docker container 1>
  - <name of docker container 2>

Steps

The steps are the actual commands that will be run during the creation or the deployment process. The steps are used in both the creation and the deploy process.

A note about the different paths

When you have to specify a path, you can use the prefix /global/ to use the root folder or your repo. (<repo>/) If nothing is specified, the script will use the VM/LXC folder (<repo>/lxc/<id>/).

Types of steps :

Scripts

Run a script from your repo

- type: script
  path: <path to script>

Run a script from an online source

- type: script
  url: <url to script>

Run a script from inside the LXC

- type: script
  lxc_path: <path to script inside the lxc>
Files

Create a file

- type: file_create
  path: <path to file>
  permissions: <permission of the file, default 644>
  owner: <owner of the file, default root:root>

Copy a file from your repo to the LXC

- type: file_copy
  path: <path to file>
  destination: <path to file inside the lxc>
  permissions: <permission of the file, default 644>
  owner: <owner of the file, default root:root>
Folders

Create a folder

- type: folder_create
  path: <path to folder>
  permissions: <permission of the folder, default 755>
  owner: <owner of the folder, default root:root>

Copy a folder from your repo to the LXC

- type: folder_copy
  path: <path to folder>
  destination: <path to folder inside the lxc>
  permissions: <permission of the folder, default 755>
  owner: <owner of the folder, default root:root>

Note: folder_copy creates the folder if it doesn't exist

Move files and folders

Move a file/folder

- type: move
  source: <path to source>
  destination: <path to destination>
  permissions: <permission of the destination folder, default 755>
  owner: <owner of the destination folder, default root:root>
Commands

Run a command inside the LXC

- type: command
  command: <command to run>
  workdir: <working directory, optional>

Run multiples commands inside the LXC

- type: command
  commands:
    - <command to run 1>
    - <command to run 2>
  workdir: <working directory, optional>
Docker

Run a command inside a docker container

- type: docker
  container: <name of docker container>
  command: <command to run>

Run multiples commands inside a docker container

- type: docker
  container: <name of docker container>
  commands:
    - <command to run 1>
    - <command to run 2>
Docker Compose

Run a docker compose command

- type: docker_compose
  command: <command to run> # ex: up -d

Note : Here, why not use the command step? Docker Compose can sometimes be executed with docker-compose or docker compose, the script will take care of choosing the correct one using this method.

Git

Clone a git repository

- type: git_clone
  url: <url of the git repository>
  destination: <path to the folder where the repo will be cloned>

Pull a git repository

- type: git_pull
  path: <path to the git repository>
Download

Download a file

- type: download
  url: <url of the file>
  destination: <path to the folder where the file will be downloaded>

Download multiple files

- type: download
  url:
    - <url of the file 1>
    - <url of the file 2>
  destination: <path to the folder where the files will be downloaded>
Packages

*Install a package *

- type: install_package
  package: <name of the package>

Install multiple packages

- type: install_package
  packages:
    - <name of the package 1>
    - <name of the package 2>

Remove a package

- type: remove_package
  package: <name of the package>

Remove multiple packages

- type: remove_package
  packages:
    - <name of the package 1>
    - <name of the package 2>

Note : all major package manager should be supported Warning : Packages can have different names depending on the Linux distribution.

Power

Reboot the LXC

- type: reboot

Stop the LXC

- type: stop

Start the LXC (should usually never be used)

- type: start
Services

Start a service

- type: service_start
  service: <name of the service>

Stop a service

- type: service_stop
  service: <name of the service>

Restart a service

- type: service_restart
  service: <name of the service>

Enable a service

- type: service_enable
  service: <name of the service>

Disable a service

- type: service_disable
  service: <name of the service>

Note: should support systemd and openrc

Replace in file (TODO)

Replace a string in a file

- type: replace_in_file
  path: <path to the file>
  search: <string to search>
  replace: <string to replace>
  case_sensitive: <true or false, default true>

Replace a string in multiple files

- type: replace_in_file
  path:
    - <path to the file 1>
    - <path to the file 2>
  search: <string to search>
  replace: <string to replace>
  case_sensitive: <true or false, default true>
Unzip

Unzip a file

- type: unzip
  path: <path to the file>
  destination: <path to the folder where the file will be unzipped>

Note: supports zip and tar.gz files

Wait

Wait X seconds

- type: wait
  seconds: <number of seconds to wait>

Global parameters

You can specific global parameters in your types:

Warning

Display a warning message in the logs

- type: <any type of step>
  warning: <text to display in logs for this step>