Example: CT Build Script for Rocky


New Member
Jul 3, 2023
I built the following scripts to automate provisioning and initial configuration of Rocky Linux 9 containers on Proxmox VE 8.0.3.

Here is the build script:
#!/bin/bash # Load secrets source /root/deploy_scripts/secrets/secrets.sh # Set CSV input file of hostnames with IP addresses input_file=hosts.csv # Set variables for contain configuration CORES=2 MEM=4096 SWAP=2048 GW= DNS= DOMAIN=lab.aftshock.com HD=16 BRIDGE=vmbr0 # Get hostnames and IPs from CSV input file tail -n +2 "$input_file" | while IFS=, read -r NAME IP _ do # Get next available container ID CT_ID=$(pvesh get /cluster/nextid) # Build new container echo "Building new container" pct create $CT_ID local:vztmpl/rockylinux-9-default_20221109_amd64.tar.xz \ --cores $CORES \ --hostname $NAME \ --memory $MEM \ --swap $SWAP \ --net0 name=eth0,bridge=$BRIDGE,firewall=1,gw=$GW,ip=$IP/24,ip6=auto,type=veth \ --searchdomain $DOMAIN \ --nameserver $DNS \ --storage local-lvm \ --rootfs local-lvm:$HD \ --unprivileged 1 \ --features nesting=1 \ --ostype centos \ --arch amd64 \ --password $ROOT_PASS \ --ssh-public-keys /root/deploy_scripts/secrets/aftsvc.pub # Add shared mount from Proxmox host pct set $CT_ID -mp0 /mnt/shared1,mp=/mnt/shared1 # Start the container pct start $CT_ID # Copy files to container for initial OS configuration and updates pct push $CT_ID /root/deploy_scripts/rocky-std-init-cfg.sh /root/rocky-std-init-cfg.sh # Execute the chmod command inside the LXC to make .sh files exc pct exec $CT_ID chmod +x /root/rocky-std-init-cfg.sh # Execute the rocky-std-init-cfg.sh file inside the LXC pct exec $CT_ID /root/rocky-std-init-cfg.sh done

Here is the script that it sent to the container and executed to update it:
#!/bin/bash # Update all packages dnf upgrade -y --refresh # Install dnf configuration manager dnf install -y dnf-utils && # Install helpful tools dnf install -y ca-certificates curl git nano ncurses openssh-server tar tmux unzip wget && # Enable SSH server systemctl enable sshd --now && # Install automatic update tools dnf install -y binutils binutils-gold dnf-automatic # Add Webmin repo cat << EOF > /etc/yum.repos.d/webmin.repo [Webmin] name=Webmin Distribution Neutral mirrorlist=https://download.webmin.com/download/yum/mirrorlist enabled=1 gpgkey=http://www.webmin.com/jcameron-key.asc EOF # Add EPEL repos dnf config-manager --set-enabled crb dnf install -y \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm && # Update all packages dnf upgrade -y --refresh && # Install additional tools dnf install -y cockpit openssl perl perl-Encode-Detect perl-IO-Tty perl-Net-SSLeay perl-Time-HiRes && # Install webmin dnf install -y webmin && # Cleanup rm /root/rocky-std-init-cfg.sh # Reboot reboot

Here is the CSV file called by the initial build script:
Hostname,IP host1, host1,

I am open to suggestions on how to improve this; I am no scripting expert. My goal is to be able to completely rebuilt and reconfigure my entire lab via a script. The above is the start; however, my plan is to also automate the installation and configuration of services (i.e.- BIND, DHCP, Docker, K3s, etc.) on select containers. I have a long way to go.

Eventually, I would love to convert this to an Ansible playbook, and maybe, even leverage APIs as opposed to the command line. Any feedback and/or help is appreciated. Thank you!
Last edited:
  • Like
Reactions: panchuz


The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!