Skip to content

Instantly share code, notes, and snippets.

@yeiichi
Last active June 16, 2025 09:39
Show Gist options
  • Save yeiichi/3fde7a7246677b6d1e4a4ae1137a8578 to your computer and use it in GitHub Desktop.
Save yeiichi/3fde7a7246677b6d1e4a4ae1137a8578 to your computer and use it in GitHub Desktop.
Setup file and directory ownership and permissions for a Django project
#!/usr/bin/env sh
set -e
# Constants
DEFAULT_GROUP="www-data"
CWD="$(pwd)" # Get current working directory immediately
VENV_DIR="${CWD}/.venv" # Define VENV_DIR relative to CWD
BACKUP_FILE="backup_$(basename "${CWD}")_$(date +%Y%m%d%H%M%S).tar.gz" # Backup file name
# Display help information
if [ "$1" = "--help" ]; then
echo "Usage: $(basename "$0")"
echo ""
echo "This script sets proper file, directory, and virtual environment permissions for a Django project."
echo "Additionally, it can create a backup of the current working directory."
echo ""
echo "Features:"
echo " - Ensures files and directories are accessible only to authorized users (root and www-data group)."
echo " - Directories: 770; Files: 660 (excluding .venv directory/files)"
echo " - Secures the virtual environment folder (.venv) with proper permissions."
echo " - Directories: 770; Files: 660; Executables in .venv/bin/: 770" # Clarified permissions
echo " - Adds a specified user to the www-data group."
echo " - Creates a compressed backup of the current working directory."
echo ""
echo "Steps:"
echo " 1. Backup your project directory using the backup utility (optional but recommended)."
echo " 2. Run this script as root user from the root directory of your Django project."
echo " 3. You will be prompted to confirm before applying changes."
echo " 4. For changes to your user's group membership to take effect, you may need to log out and back in."
echo ""
echo "Example:"
echo " sudo $(basename "$0")"
echo " sudo $(basename "$0") --backup"
echo ""
exit 0
fi
# Helper to print warnings in yellow
print_in_yellow() {
printf "\033[93m%s\033[0m\n" "$1"
}
# Ensure script is run as root
[ "$(id -u)" -ne 0 ] && print_in_yellow "This script must be run as root." && exit 1
# Print warnings
print_warnings() {
print_in_yellow "You are now in: ${PWD}"
print_in_yellow " - Make sure that the current working directory is the Django project root."
print_in_yellow " - The specified user will be added to the ${DEFAULT_GROUP} group."
print_in_yellow " - We strongly recommend backing up the current directory and files before proceeding."
print_in_yellow "Use '--help' for more information."
}
# Backup current working directory
backup_cwd() {
echo "Creating a backup of the current working directory..."
tar czf "${BACKUP_FILE}" -C "${CWD}" . --exclude="./.venv"
echo "Backup created: ${BACKUP_FILE}"
}
# Add user to group
add_user_to_www_data_group() {
if ! id -nG "${YOUR_USER}" | grep -qw "${DEFAULT_GROUP}"; then
echo "Adding user '${YOUR_USER}' to group '${DEFAULT_GROUP}'..."
usermod -aG "${DEFAULT_GROUP}" "${YOUR_USER}"
print_in_yellow "Please remember to log out and log back in for group changes to take effect for user '${YOUR_USER}'."
else
echo "User '${YOUR_USER}' is already a member of group '${DEFAULT_GROUP}'."
fi
}
# Change ownership of all files/directories (excluding .venv for now, handled later for specificity)
set_default_ownership() {
echo "Setting ownership to root:${DEFAULT_GROUP} for project files (excluding .venv)..."
find "${CWD}" -path "${VENV_DIR}" -prune -o -exec chown root:"${DEFAULT_GROUP}" {} +
echo "Done."
}
# Set permissions for project files and directories (excluding .venv)
set_project_permissions() {
echo "Setting permissions for project directories (770) and files (660)..."
find "${CWD}" -path "${VENV_DIR}" -prune -o -type d -exec chmod 770 {} +
find "${CWD}" -path "${VENV_DIR}" -prune -o -type f -exec chmod 660 {} +
echo "Done."
}
# Secure `.venv` directory
set_venv_attributes() {
echo "Setting ${VENV_DIR} ownership and permissions..."
chown -R root:"${DEFAULT_GROUP}" "${VENV_DIR}"
find "${VENV_DIR}" -type d -exec chmod 770 {} +
find "${VENV_DIR}" -type f \( -perm /u+x,g+x,o+x -o -path "${VENV_DIR}/bin/*" \) -exec chmod 770 {} +
find "${VENV_DIR}" -type f ! -perm /u+x,g+x,o+x ! -path "${VENV_DIR}/bin/*" -exec chmod 660 {} +
echo "Done."
}
# Main function
main() {
print_warnings
# Offer backup option before proceeding
printf "\033[93mDo you want to create a backup? (Y/N): \033[0m"
read -r backup_choice
if [ "${backup_choice}" = "Y" ]; then
backup_cwd
fi
printf "\033[93mOK to proceed? (Y/N): \033[0m"
read -r user_choice
[ "${user_choice}" != "Y" ] && echo "Exiting..." && exit 1
printf "\033[93mEnter the username you want to add to the %s group: \033[0m" "${DEFAULT_GROUP}"
read -r YOUR_USER
# Run main setup steps
add_user_to_www_data_group
set_default_ownership
set_project_permissions
set_venv_attributes
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment