Complete Guide: Creating a Secure, Portable Python Development Environment on a USB Drive (with git)
Complete Guide: Creating a Secure, Portable Python Development Environment on a USB Drive
This guide will walk you through the entire process of setting up a GDPR-compliant, encrypted, and portable Python development environment on a USB stick using Ubuntu. The final result will be a self-contained project, securely linked to a GitHub repository.
Goal: To create a secure space on a USB drive to develop a Python application, manage its dependencies, and version control it with Git and GitHub, ensuring that all code, data, and credentials remain on the encrypted drive.
Prerequisites:
An Ubuntu system.
A USB drive (at least 8GB recommended). Warning: All data on this drive will be permanently erased.
An empty repository created on your GitHub account.
Step 1: Create the Secure Encrypted USB Drive
First, we create a secure "vault" on the USB drive using LUKS, the standard encryption tool for Linux.
Insert the USB drive.
Open the Disks application from your Ubuntu menu.
Carefully select your USB drive from the list on the left.
Click the top-right menu (three dots) and select Format Disk.... Choose GPT partitioning and click Format... to wipe the drive.
You will now see "Free Space". Click the
+
icon to create a new partition.In the dialog box:
Volume Name: Give it a clear name (e.g.,
Secure-Vault
).Type: Select "Internal disk for use with Linux systems only (Ext4)".
Enable Password Protection: Check the box that says "Password protect volume (LUKS)".
Click Next and set a strong password. This password protects all your data. If you lose it, the data is unrecoverable.
Click Create. The drive is now encrypted.
Step 2: Mount the Drive and Create Your Project Folder
Unplug and re-plug the USB drive.
Open the File Manager. You will see your drive with a lock icon. Click it and enter the password you just created to unlock (mount) it.
Open a Terminal window.
Navigate into your newly mounted drive. The path will be similar to this (replace
your_username
andSecure-Vault
accordingly):cd /media/your_username/Secure-Vault/
Create a directory for your Python project:
mkdir my_secure_app cd my_secure_app/
You are now inside your project folder on the encrypted drive. All subsequent commands should be run from here.
Step 3: Configure Your Git Identity
Tell Git who you are. This identity is used in every commit you make.
Set your name:
git config --global user.name "Your Name"
Set your email address (use the one associated with your GitHub account):
git config --global user.email "your_email@example.com"
Step 4: Initialize the Git Repository
Turn your project folder into a Git repository to start tracking changes.
git init
Step 5: Create the Python Virtual Environment
Create a self-contained environment for your Python packages.
Create the virtual environment folder, named
venv
:python3 -m venv venv
Activate the environment. This is a crucial step you must do every time you work on the project.
source venv/bin/activate
Your terminal prompt will now start with
(venv)
, indicating the environment is active.
Step 6: Link to GitHub with a Secure SSH Key
We will create a new SSH key stored securely on the USB, so you don't need to enter a password to interact with GitHub.
Generate the SSH Key:
ssh-keygen -t ed25519 -C "your_email@example.com"
When prompted
Enter file in which to save the key:
, provide a path inside your project folder. This keeps the key on the encrypted drive./media/your_username/Secure-Vault/my_secure_app/.ssh/id_ed25519
When prompted for a passphrase, press Enter twice to leave it empty. The key is already protected by the drive's encryption.
Add the Public Key to GitHub:
Display the public key in your terminal and copy the entire output:
cat .ssh/id_ed25519.pub
In your web browser, go to your GitHub Settings > SSH and GPG keys.
Click New SSH key, give it a title (e.g., "Secure USB Key"), paste the copied key into the "Key" box, and click Add SSH key.
Link Your Local Repo to GitHub:
On your GitHub repository page, click the green
< > Code
button, select the SSH tab, and copy the URL (e.g.,git@github.com:your_username/your_repo.git
).Back in your terminal, add this as the remote "origin":
git remote add origin git@github.com:your_username/your_repo.git
Configure Git to Use the New SSH Key (Crucial Step):
Because the SSH key is in a non-standard location (inside your project folder), you must tell this specific repository how to find it.
Run this command:
git config core.sshCommand "ssh -i .ssh/id_ed25519"
Step 7: Create a .gitignore
File
Create a file to tell Git which files and folders to ignore. This is critical for preventing sensitive data and unnecessary files from being uploaded.
Create the file:
touch .gitignore
Open the
.gitignore
file with a text editor and add the following:# Python Virtual Environment & SSH key venv/ .ssh/ # Database files *.db *.sqlite3 *.db-journal # Python cache files __pycache__/ *.pyc # IDE / Editor folders .vscode/ .idea/ # OS-specific files .DS_Store lost+found/
Step 8: Make Your First Commit and Push
Now, save your work to GitHub for the first time.
Add all your project files to Git's tracking (it will respect the
.gitignore
rules):git add .
Commit the files with a message:
git commit -m "Initial project setup with secure environment"
Push your code to GitHub:
git push -u origin main
(Note: If your repository's default branch is
master
, usegit push -u origin master
instead).
Congratulations! You now have a fully functional, secure, and portable Python development environment.
Step 9: Troubleshooting Common First-Time Issues
If you encounter an error during your first git push
, it's likely one of these two common issues.
Issue 1: Permission denied (publickey)
If you see this error:
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
What it means: Git tried to connect to GitHub, but it didn't present the correct SSH key. This usually happens if you miss or mistype the command in Step 6, part 6.
How to fix: Rerun the configuration command from within your project directory to ensure your repository knows which key to use:
git config core.sshCommand "ssh -i .ssh/id_ed25519"
Then try
git push
again.
Issue 2: fatal: The current branch ... has no upstream branch
If you see this message:
fatal: The current branch master has no upstream branch.
What it means: This isn't an error, but a one-time question from Git. Your local branch (
master
ormain
) doesn't know which branch on the remote server (origin
) to connect to.How to fix: Simply use the full command that Git suggests. This command pushes your code and permanently "links" your local branch to the remote one.
git push --set-upstream origin master
(Or replace
master
withmain
if that's your branch name). For all future pushes, you will only need to typegit push
.
Deeper Dive: Understanding the "Why" Behind the Commands
This section explains the concepts behind the steps for those who want to understand the process more deeply.
Step 1: Encryption (LUKS)
What is LUKS? LUKS (Linux Unified Key Setup) is the standard framework for disk encryption in Linux. It doesn't just encrypt the data; it also securely manages the password and encryption keys. By using the standard, you ensure your drive can be opened by nearly any modern Linux system.
Why format the disk? Formatting a disk prepares it for use by creating a new, clean filesystem. We do this to ensure there are no remnants of old data or structures. Choosing GPT (GUID Partition Table) is the modern standard for laying out partitions on a disk.
Why is this GDPR compliant? GDPR requires you to take "appropriate technical and organisational measures" to protect personal data. Full-disk encryption is a gold-standard technical measure. If the USB drive is lost or stolen, the data is unreadable without the password, rendering it useless to a thief and preventing a data breach.
Step 2: Mounting
What is "mounting"? An encrypted volume is just a block of scrambled data. "Mounting" is the process of unlocking that data with your password and making it appear as a normal, accessible folder in your system's file structure (e.g., at
/media/your_username/Secure-Vault
). When you "unmount" or "eject" the drive, you are locking the vault again.
Step 3: Git Identity (
git config --global
)Why does Git need an identity? Git is a version control system. Every change is logged against a person. This configuration tells Git who "you" are, so every commit you make is stamped with your name and email. The
--global
flag saves this configuration for your user account on this computer, so you don't have to set it for every new project.
Step 4: Git Init
What does
git init
really do? It creates a hidden sub-folder named.git
. This folder is the "brain" of your repository. It contains all the snapshots of your code, the full history of every commit, and the configuration for this specific project. All of Git's magic happens inside this.git
directory.
Step 5: Virtual Environment (
venv
)Why is this so important? Your main computer has one set of "system" Python packages. If Project A needs version 1.0 of a package, and Project B needs version 2.0, you have a conflict. A virtual environment creates an isolated, private installation of Python and its packages inside your project folder.
How does
source venv/bin/activate
work? It's a clever trick. It temporarily modifies your terminal'sPATH
variable. ThePATH
is the list of places your terminal looks for commands. Theactivate
script puts your localvenv/bin
folder at the very front of this list. So, when you typepython
, it finds the one invenv/bin
first, instead of the system-wide one.
Step 6: SSH Keys
What is SSH? SSH (Secure Shell) is a secure protocol for communicating with another computer. Public-key cryptography is its core security feature.
How do the keys work? You generate a mathematically linked pair: a private key (which you keep secret) and a public key (which you can share freely). The public key acts like an open padlock. You put this "padlock" on your GitHub account. The only key in the universe that can unlock it is your private key. When you
git push
, your computer uses your private key to prove its identity to GitHub's padlock. This is far more secure than a password, which can be stolen or guessed.Why
git config core.sshCommand
? Git's default behavior is to look for SSH keys in a standard system location (~/.ssh/
). Because we created our key in a special location (my_secure_app/.ssh/
), we have to explicitly tell this specific repository, "Don't use the default path; use this special command to point to the key right here in this folder."
Step 7:
.gitignore
Why ignore files? A Git repository should only contain the source code—the essential blueprints needed to build and run the project. You should ignore:
Secrets: Like your
.ssh/
folder!Dependencies: Like the
venv/
folder. The list of dependencies should be saved (e.g., in arequirements.txt
file), but not the packages themselves. Anyone else using your project should create their ownvenv
and install the packages from the list.Generated Files: Like databases (
.db
) or cache files (__pycache__/
). These are created by the program when it runs, they are not part of the source.Hidden System Files: Different operating systems create their own hidden files and folders for housekeeping. These are irrelevant to your project's code and can cause issues.
lost+found/
: This is created by the Linux Ext4 filesystem. It's used for data recovery if the system crashes, but it's not part of your project..DS_Store
: This is created automatically by macOS's Finder to store custom attributes of a folder, like the position of icons. It's useless on other systems.
Step 8: Commit and Push
The Two-Stage Save: This is the fundamental Git workflow.
git commit
: Records a snapshot of your changes to the local.git
folder's history. You can do this many times, even when offline. It's like saving a draft of a document.git push
: Uploads your committed changes from your local repository to the remote server (GitHub). This is how you share your work and back it up. The-u
(or--set-upstream
) flag is a one-time command on the first push to establish the connection between your local branch and the remote one.
Comments
Post a Comment