This repository serves as a template for Python projects, leveraging the power of Docker and Visual Studio Code's development containers.
The main components of this template are:
- A
Dockerfile
that sets up a Python environment and installs necessary dependencies. - A
devcontainer.json
file that configures how VS Code should use our Docker environment.
The Dockerfile is a script that Docker executes to build a Docker image. This file contains a series of instructions telling Docker what base image to use, what files to copy over, what commands to run, and more.
Here's a brief summary of what our Dockerfile does:
- Starts from a Python base image (Version can be set in
devcontainer.json
under the"Variant"
argument). - Sets a working directory.
- Optionally installs additional OS packages.
- Optionally sets up GPU support.
- Copies the
requirements.txt
file into the container. - Installs the Python dependencies.
- Copies your application into the container.
You can customize your Dockerfile according to your project requirements. To uncomment any section, just remove the "#" character at the beginning of the line.
Here are step by step instructions to add a new software to your Dockerfile:
-
Identify the command to install your software. This command will differ based on the software and the base image's operating system. For Debian based distributions, you'll typically use
apt-get install
. -
Add a new
RUN
instruction to your Dockerfile with this command. It's a good practice to clean up after your installation to keep the Docker image size small. A typical install instruction may look like this:
RUN apt-get update && apt-get install -y \
your-software \
&& rm -rf /var/lib/apt/lists/*
- Rebuild your Docker image. You can do this in VS Code by pressing
F1
, then typing "Rebuild Container".
This file configures how VS Code should use our Docker container. Some of its main features are:
- Defines the Dockerfile for the build.
- Specifies a list of extensions to be installed automatically.
- Defines a list of ports to forward from the container to the host machine.
- Specifies a command to run after the container is created.
- Sets up a specific user to avoid permission issues.
Much like the Dockerfile, you can customize this file to better fit your project. To uncomment any line, simply remove the "//" characters at the beginning of the line.
Remember, the goal of using a dev container is to provide a consistent and reproducible development environment. Take the time to carefully define what goes into your Dockerfile and devcontainer.json
files, and your team (or future you) will thank you!
In this template, we manage Python libraries and dependencies through requirements.txt
file and Python virtual environments.
To install new libraries:
- Install in the Docker Container: You can install libraries directly into the Docker container using pip. For example:
pip install numpy
- Add to
requirements.txt
: If you want the library to be included every time the Docker container is built, add the library to yourrequirements.txt
file:
numpy==1.21.0
- Rebuild the Docker Container: In VS Code, you can rebuild the Docker container by pressing
F1
, then typing and selecting "Remote-Containers: Rebuild Container". This will reinstall all libraries listed inrequirements.txt
.
If you're working with subprojects that have different dependencies, it's ideal to use Python virtual environments for isolation. Here are the steps to create an isolated environment for a subproject:
- Create a Subproject Directory: Within your main project, create a directory for each subproject.
/my_main_project
/subproject1
/subproject2
...
- Create a Virtual Environment: Within each subproject directory, create a new Python virtual environment using the
venv
module:
python -m venv ./venv
This will create a new directory called venv
within your subproject directory, which will contain a copy of the Python interpreter, the standard library, and various supporting files.
- Activate the Virtual Environment: Before you start working on a subproject, activate the virtual environment:
source ./venv/bin/activate
- Install Subproject Dependencies: Now you can install any Python libraries that are specific to the subproject. These libraries will be installed within the virtual environment and will not affect your main project or other subprojects. You can create a separate
requirements.txt
file for each subproject and install the libraries using pip:
pip install -r requirements.txt
- Deactivate the Virtual Environment: When you're done working on a subproject, you can deactivate the virtual environment:
deactivate
Remember to reactivate the virtual environment each time you start a new terminal session and want to work on a subproject.
When using this Docker container for development, there are a few things to keep in mind:
-
Persistence: Anything you install or any data you create within the container will be lost once the container is removed. To keep data between runs, use Docker volumes to persist data in specified directories. In this template, the entire project directory is mounted as a volume, so your project files are persisted between runs.
-
Permissions: The Dockerfile is set up to run commands as root. This can cause permission issues with files created within the container, as they will also be owned by root. If this causes problems, you can uncomment the
remoteUser
line indevcontainer.json
to run commands as a non-root user. -
Port Forwarding: By default, the ports specified in
forwardPorts
indevcontainer.json
will be forwarded from the container to the host. If you need other ports to be accessible, add them to this list. -
Environment Variables: If your application needs certain environment variables to be set, you can use the
env
field indevcontainer.json
.
By keeping these points in mind, you can avoid common issues and make the most of using this Docker container for development.
- After setup and building your development container, you can open a terminal in VS Code by pressing
Ctrl + Shift + ~
. This will open a terminal within the container, where you can run commands likepython
. You can also open a terminal on your host machine by pressingCtrl + Shift + C
. - Your project directory (where the
.devcontainer
folder is located) is mounted as a volume in the container. This means that any changes you make to your project files will be reflected in the container, and vice versa. The folder/workspace
should contain this project directory where you can find your project files.
docker ps
- List all running containersdocker ps -a
- List all containersdocker images
- List all imagesdocker rm <container_id>
- Remove a containerdocker rmi <image_id>
- Remove an imagedocker exec -it <container_id> bash
- Open a bash terminal in a running containerdocker build -t <image_name> .
- Build a Docker image from a Dockerfile
ls
- List files in current directoryls -a
- List all files in current directoryls -l
- List files in current directory with detailsls -la
- List all files in current directory with detailscd ..
- Go up one directorycd ~
- Go to home directorycd -
- Go to previous directorycd /
- Go to root directorycd <directory>
- Change directorypwd
- Print working directorymkdir <directory>
- Create a new directoryrm <file>
- Remove a filerm -r <directory>
- Remove a directorycp <file> <new_file>
- Copy a filecp -r <directory> <new_directory>
- Copy a directorymv <file> <new_file>
- Move a filemv <directory> <new_directory>
- Move a directorycat <file>
- Print contents of a filehead <file>
- Print first 10 lines of a filetail <file>
- Print last 10 lines of a fileless <file>
- View a filedu -sh <directory>
- Get size of a directoryfree -h
- Get free memorydf -h
- Get free disk spacetop
- View running processeskill <process_id>
- Kill a processkillall <process_name>
- Kill all processes with a given nameps
- List running processesps -a
- List all processesps -u <user>
- List processes for a given userps -aux
- List all processes with detailsps -aux | grep <process_name>
- List all processes with details and filter by namechmod +x <file>
- Make a file executablechmod -x <file>
- Make a file not executablechmod 777 <file>
- Give all permissions to a filechmod 000 <file>
- Remove all permissions from a filechown <user> <file>
- Change the owner of a filechown -R <user> <directory>
- Change the owner of a directory and all its contentschgrp <group> <file>
- Change the group of a filewatch -n<seconds> <command>
- Run a command every n secondscurl <url>
- Make a GET request to a URLcurl -X POST <url>
- Make a POST request to a URLcurl -X PUT <url>
- Make a PUT request to a URLcurl -X DELETE <url>
- Make a DELETE request to a URL
python version
- Get Python versionpython <file>
- Run a Python filepython -h
- Get help for Pythonpython -c "print('Hello World!')"
- Run a Python commandpython -m venv <directory>
- Create a Python virtual environmentsource <directory>/bin/activate
- Activate a Python virtual environmentdeactivate
- Deactivate a Python virtual environmentpython -m pip install --upgrade pip
- Upgrade pippip install <package>
- Install a Python packagepip install -r <requirements_file>
- Install Python packages from a requirements filepip freeze
- List installed Python packagespip freeze > <requirements_file>
- Save installed Python packages to a requirements filepip uninstall <package>
- Uninstall a Python packagepip uninstall -r <requirements_file>
- Uninstall Python packages from a requirements filepip show <package>
- Show information about a Python packagepip search <package>
- Search for a Python packagepip list
- List installed Python packagespip list --outdated
- List outdated Python packagespip list --uptodate
- List up-to-date Python packagespip list --format=json
- List installed Python packages in JSON formatpip list --format=yaml
- List installed Python packages in YAML formatpip list --format=csv
- List installed Python packages in CSV formatpip list --format=freeze > <requirements_file>
- Save installed Python packages to a requirements file