This blog post describes how to generate your own DietPi LXC container template in the Proxmox VE. Based on the template you can then instantiate LXC containers.
Table of contents
1. Overview
The generation is done in the following steps:
- Generation of a DietPi VM
- Conversion of the VM to a LXC container using the script described below
- Conversion of the LXC container to an LXC container template
- Have fun
The basis for your LXC container is a Proxmox DietPi VM which you want to convert to a Proxmox LXC container template. Find it with install instructions at our download page: https://dietpi.com/#download
2. Conversion script
The conversion script is based on Sascha Basts GitHub page. I did some minor changes to this script.
Important: The script runs in the Proxmox VE console, so you need to login as root onto your Proxmox machine, edit the script and run it on your machine (with root rights).
Generate a script convert-vm-to-lxc.sh
with an editor and set it to executable viachmod +x convert-vm-to-lxc.sh
.
#!/bin/bash
usage()
{
cat <<EOF
$1
-h|--help
-n|--name [target lxc container name]
-t|--target [source virtual machine ssh uri (IP or hostname)]
-i|--id [target lxc container proxmox container id]
-s|--root-size [target lxc container rootfs size in GB]
-m|--memory [target lxc container memory in MB]
-c|--cores [target lxc container cpu cores]
-p|--password [root password for target lxc container (min. 5 chars)]
EOF
return 0
}
options=$(getopt -o n:t:i:s:m:c:p:f -l help,name:,target:,id:,root-size:,memory:,cores:,password:,foo: -- "$@")
if [ $? -ne 0 ]; then
usage $(basename $0)
exit 1
fi
eval set -- "$options"
while true
do
case "$1" in
-h|--help) usage $0 && exit 0;;
-n|--name) name=$2; shift 2;;
-t|--target) target=$2; shift 2;;
-i|--id) id=$2; shift 2;;
-s|--root-size) rootsize=$2; shift 2;;
-m|--memory) memory=$2; shift 2;;
-c|--cores) cores=$2; shift 2;;
-p|--password) password=$2; shift 2;;
--) shift 2; break ;;
*) break ;;
esac
done
collectFS() {
tar -czvvf - -C / \
--exclude="sys" \
--exclude="dev" \
--exclude="run" \
--exclude="proc" \
--exclude="*.log" \
--exclude="*.log*" \
--exclude="*.gz" \
--exclude="*.sql" \
--exclude="swap.img" \
.
}
ssh "root@$target" "$(typeset -f collectFS); collectFS" \
> "/tmp/$name.tar.gz"
pct create $id "/tmp/$name.tar.gz" \
--description LXC \
--hostname $name \
--features nesting=1 \
--memory $memory \
--cores $cores \
--net0 name=eth0,ip=dhcp,ip6=auto,bridge=vmbr0,firewall=1 \
--rootfs $rootsize --storage local-lvm --password $password
rm -rf "/tmp/$name.tar.gz"
Remarks
- The entry
ip6=auto
is comparable to this Proxmox setting: - If you run the script, care for enough disk space on your Proxmox VE, because the script generates a temporary file which can be large:
- The script first generates a
/tmp/<target lxc container name>.tar.gz
- It then uses the
pct create
command to generate an LXC container - At lease the file
/tmp/<target lxc container name>.tar.gz
is deleted
- The script first generates a
3. Conversion
3.1 Step 1: Convert VM to LXC container
Execute the script like this:
./convert-vm-to-lxc.sh -n lxc-test -t lxc-conv-test.fritz.box -i 153 -s 4 -c 1 -m 2048 -p dietpi
The script example generates an LXC container called lxc-test
from the base DietPi VM lxc-conv-test
with the container ID 153 (see screenshot at the top) with a 4 GiB root disk size, one CPU core, 2 GiB memory and dietpi
as the root password of the new container.
In case of script problems, first find out the script options via ./convert-vm-to-lxc.sh --help
and check whether your command line options are correct:
./convert-vm-to-lxc.sh
-h|--help
-n|--name [target lxc container name]
-t|--target [source virtual machine ssh uri (IP or hostname)]
-i|--id [target lxc container proxmox container id]
-s|--root-size [target lxc container rootfs size in GB]
-m|--memory [target lxc container memory in MB]
-c|--cores [target lxc container cpu cores]
-p|--password [root password for target lxc container (min. 5 chars)]
To let DietPi know that it is a container and no VM anymore, the following change should be done:
- Change the value in
/etc/.dietpi_hw_model_identifier
from 20 to 75. - If you are doing this within the running container, either
reboot
, or run the following two commands:
/boot/dietpi/func/dietpi-obtain_hw_model
source /boot/dietpi/.hw_model
And finally, as a container does not require any bootloader, initramfs and kernel, you should purge them all:
apt autopurge grub-pc tiny-initramfs linux-image-amd64
3.2 Step 2: Convert LXC container to LXC container template
Finally, you might convert your new LXC container to a template for later usage:
Remark
If you are faced with the problem that an LXC container generated shows dietpi-cloudshell
messages on your console, you can get rid of it by executing the following command before you convert it to an LXC container template:
systemctl disable --now dietpi-cloudshell systemd-networkd systemd-resolved
Proxmox seems to enable some services as part of the necessary VLAN network setup, but also the completely unrelated dietpi-cloudshell
service.
4. Thushan’s convenient conversion script (GitHub)
On GitHub, thushan generated a nice conversion script Proxmox VM to Container called proxmox-vm-to-ct.
See also his reply below and the script description in his private blog.
5. References
- GitHub: Convert any gnu/linux machine into a proxmox lxc container
- Proxmox VE documentation: pct – Tool to manage Linux Containers (LXC) on Proxmox VE
- Michael Bachmann: Proxmox VM in einen LXC Container konvertieren
- Thushan’s conversion script: proxmox-vm-to-ct resp. Converting Proxmox VMs to Containers Easily!
I get tis:
root@GateKeeper:~/DietPi/proxmox-dietpi-installer# ./convertStS.sh -n lxc-test -t lxc-conv-test.fritz.box -i 153 -s 4 -m 2048 -p dietpi
ssh: Could not resolve hostname lxc-conv-test.fritz.box: Name or service not known
400 too many arguments
pct create [OPTIONS]
Which VM did you want to convert?
See above in the script about the command line option -t.
Could you also add a -c 1 or -c 2 (or whatever cores you want to use) to your script call?
Hi, after executing script i’ve got the following error
400 too many arguments
pct create [OPTIONS]
i use same argument in your example
Thanks
Which Proxmox VE release do you use?
Can you post the command line you used (possibly some misentered arguments)?
./jmdietpi.sh -n lxc-dietpilxc -t 192.168.8.84 -i 131 -s 4 -m 2048 -p dietpi
proxmox version 7.3.6
So you do not have any present VM or LXC container with ID 131, you have a DietPi VM with IP 192.168.8.84 where you can login via ssh (ssh root@192.168.8.84) and you do not have any present VM or LXC container with the name lxc-dietpilxc?
i add -c 2 and it works, ive just used your example and -c isnt in it.
regards
Ok, I add at least c 1 in the example. Thx for your investigation.
In the Container i’ve got the Message “A reboot is required to finalise a recent kernel upgrade” but Rebooting the LXC doesnt change anything? What can i do?
Ah, the guide misses the steps to purge kernel, initramfs and bootloader, which are all not needed within a container, or course. But the check should be actually skipped in containers. Did you apply the last step to change the hardware ID? And could you show the output of:
To purge unneeded packages:
hi can we do this for dietpi 7 also?
TASK ERROR: Template feature is not available for ‘VM-LXC:vm-102-disk-0’
Would you please share some more information? What did you do to come to this message?
I follow all the steps in this page to generate the new lxc container based on dietPI Vm flawless
but when i try to convert this new lxc diepi container in a template y get that error.
No clue. At my PVE it works (before converting to an LXC template I had to poweroff the LXC container).
In instructions, there is an extra space in
chmod + x convert-vm-to-lxc.sh
should be
chmod +x convert-vm-to-lxc.sh
Many thanks for the hint, I fixed it :).
I get always asked for a Password but I can´t find one?
Can some one help.
Do you mean the password used for the -p optoin of the script?
This is the root password of the generated lxc container to log in.
Typically, you could use ‘dietpi’ as the default lxc container password like described in the blog post.
LXC Container works fine, can be accessed per IP but using the Hostname for the LXC Container doesnt work, everytime timeout. Dietpi Install as non-LXC Container Hostname Access is no Problem. Do i have to change something in the LXC?
Does the container receive an own IP address via DHCP, independent from its host, and appears as dedicated device in the router/DHCP server? Usually, if a DHCP client leases an IP address, the router obtains its hostname and stores it with the IP for local DNS resolution. But this only works if it appears as dedicated device, i.e. in bridged network mode. An alternative would be to use mDNS, e.g. install Avahi-Daemon via
dietpi-software
, which will broadcast the hostname to the network without the router/DHCP/DNS server being involved. It then has “.local” as top level domain by default, e.g. “mycloud.local”.My DietPi lxc container work fine with calling them via their hostname (e.g. lxc-test.fritz.box).
What are the advanteges of convertion a DietPi VM into an LXC Container over installing from a Debian LXC Template and converting Debian to DietPi with this script?
https://dietpi.com/docs/hardware/#make-your-own-distribution
If I’m not mistaken, the LXC container requires an own network tools stack, and the DietPi-Installer “Container” selection removes all network tools, including ifupdown, assuming the host network is used directly. A network-capable container option, i.e. that works for containers with their own subnet sandbox would need to be implemented first.
And converting a VM into a container should be also faster compared to running the installer.
At first, I tried the converting script running on a basic Debian image. That did fail in the area of the network. Whether the script might be extended to be capable doing a LXC container conversion was not tested, because before examining this, I did the conversion with the conversion script.
Tried your script. But it did not work.
I guess because you have hard-code storage to “local-lvm”.
LVM is very old stylish. I’m grateful that I was able to blast it everywhere.
Proxmox works much more smooth with ZFS or even BTRFS on smaller hardware.
Since BTRFS did not run Raid5/10 reliable LVM may be an option in conjuction with the old good mdadm. Other raid modes linke 0, 1 works perfect.
I’ve wrapped this into a script and just published it, makes it a bit easier to manage DietPi to Container workloads. Still in the early days and I’ve got a bit more work to do to reuse configs/images etc.
https://github.com/thushan/proxmox-vm-to-ct
Thank you this worked perfectly. We converted 37 vms to containers today with your script. 2 failed because of network issue in our end at start. Very nice.
Thanks Fernando this is very good. We spent last week trying to convert some VM from VMWare to PrixMox and now thanks to this script we changed all to containers in no time. we will send you dutch beers.
many thanks fernando!!! you made my day. it can be repeated over and over for lots of vms. so now we changed to create 1 “big vm” for our customers then create container when new customer asks and keep big vm updated with latest image. Also works with Debian and Ubuntu VM which we are using. Really like simple and good looking script like this. Makes my job very easy! No more VMWare so all of us are moving to Proxmox!
wow very easy script. password feature very good. trying on dp7 and it is working, 谢谢