From d1e170119eeed5c6be920069bac70a4cb4963ae3 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Tue, 31 Mar 2020 19:23:03 +0000 Subject: [PATCH] Update to use Python pre-built image --- .devcontainer/Dockerfile | 82 ++++++++++++--------------------- .devcontainer/devcontainer.json | 48 +++++++++++-------- README.md | 4 +- 3 files changed, 61 insertions(+), 73 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6e8d67e..567fa1b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -3,60 +3,36 @@ # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- -FROM python:3 +# Update the VARIANT arg in devcontainer.json to pick a Python version: 3, 3.8, 3.7, 3.6 +# To fully customize the contents of this image, use the following Dockerfile instead: +# https://github.com/microsoft/vscode-dev-containers/tree/v0.109.0/containers/python-3/.devcontainer/base.Dockerfile +ARG VARIANT=3 +FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} -# Avoid warnings by switching to noninteractive -ENV DEBIAN_FRONTEND=noninteractive - -# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" -# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs -# will be updated to match your local UID/GID (when using the dockerFile property). -# See https://aka.ms/vscode-remote/containers/non-root-user for details. -ARG USERNAME=vscode -ARG USER_UID=1000 -ARG USER_GID=$USER_UID - -ENV PIP_TARGET=/usr/local/share/pip-global -ENV PYTHONPATH=${PYTHONPATH}:${PIP_TARGET} -ENV PATH=${PATH}:${PIP_TARGET}/bin - -# Uncomment the following COPY line and the corresponding lines in the `RUN` command if you wish to -# include your requirements in the image itself. It is suggested that you only do this if your -# requirements rarely (if ever) change. +# [Optional] If your requirements rarely change, uncomment this section to add them to the image. +# # COPY requirements.txt /tmp/pip-tmp/ +# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ +# && rm -rf /tmp/pip-tmp -# Configure apt and install packages -RUN apt-get update \ - && apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \ - # - # Verify git, process tools, lsb-release (common in install instructions for CLIs) installed - && apt-get -y install git iproute2 procps lsb-release \ - # - # Install pylint - && pip --disable-pip-version-check --no-cache-dir install pylint \ - # - # Update Python environment based on requirements.txt - # && pip --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \ - # && rm -rf /tmp/pip-tmp \ - # - # Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user. - && groupadd --gid $USER_GID $USERNAME \ - && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ - # [Optional] Add sudo support for the non-root user - && apt-get install -y sudo \ - && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\ - && chmod 0440 /etc/sudoers.d/$USERNAME \ - # - # Create alternate global install location that both uses have rights to access - && mkdir -p /usr/local/share/pip-global \ - && chown ${USERNAME}:root /usr/local/share/pip-global \ - # - # Clean up - && apt-get autoremove -y \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - -# Switch back to dialog for any ad-hoc use of apt-get -ENV DEBIAN_FRONTEND=dialog - +# [Optional] Create alternate global install location where the vscode user can write w/o sudo +ENV PIP_TARGET=/usr/local/pip-global +ENV PYTHONPATH=${PIP_TARGET}:${PYTHONPATH} +ENV PATH=${PIP_TARGET}/bin:${PATH} +RUN mkdir -p ${PIP_TARGET} \ + && chown vscode:root ${PIP_TARGET} \ + && export SNIPPET="if [ \"\$(stat -c '%U' ${PIP_TARGET})\" != \"vscode\" ]; then chown -R vscode:root ${PIP_TARGET}; fi" \ + && echo "$SNIPPET" | tee -a /root/.bashrc >> /home/vscode/.bashrc \ + && echo "$SNIPPET" | tee -a /root/.zshrc >> /home/vscode/.zshrc +# [Optional] Uncomment this section to install additional packages. +# +# ENV DEBIAN_FRONTEND=noninteractive +# RUN apt-get update \ +# && apt-get -y install --no-install-recommends \ +# # +# # Clean up +# && apt-get autoremove -y \ +# && apt-get clean -y \ +# && rm -rf /var/lib/apt/lists/* +# ENV DEBIAN_FRONTEND=dialog diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1e8d2e5..652ae35 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,30 +1,42 @@ { - "name": "Python 3", - "context": "..", - "dockerFile": "Dockerfile", + "name": "Python 3 Sample", + "build": { + "dockerfile": "Dockerfile", + "context": "..", + // Update 'VARIANT' to pick a Python version. Rebuild the container + // if it already exists to update. Available variants: 3, 3.6, 3.7, 3.8 + "args": { "VARIANT": "3.7" } + }, - // Use 'settings' to set *default* container specific settings.json values on container create. - // You can edit these settings after create using File > Preferences > Settings > Remote. + // Set *default* container specific settings.json values on container create. "settings": { "terminal.integrated.shell.linux": "/bin/bash", "python.pythonPath": "/usr/local/bin/python", "python.linting.enabled": true, "python.linting.pylintEnabled": true, - "python.linting.pylintPath": "/usr/local/share/pip-global/bin/pylint" + "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", + "python.formatting.blackPath": "/usr/local/py-utils/bin/black", + "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", + "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", + "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", + "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", + "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint", + "python.testing.pytestPath": "/usr/local/py-utils/bin/pytest" }, - // Use 'appPort' to create a container with published ports. If the port isn't working, be sure - // your server accepts connections from all interfaces (0.0.0.0 or '*'), not just localhost. - "appPort": [ 9000 ], - - // Install flask and any other dependencies - "postCreateCommand": "pip install -r requirements.txt", - - // Comment out next line to run as root - "remoteUser": "vscode", - - // Add the IDs of extensions you want installed when the container is created in the array below. + // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-python.python" - ] + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [9000], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "pip3 install -r requirements.txt", + + // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode" } diff --git a/README.md b/README.md index 98d3832..cae1fe5 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ Some things to try: - Try adding some code and check out the language features. 2. **Terminal:** - Press ctrl+shift+\` to open a terminal window. - - Type `python -m flask run --host 0.0.0.0 --port 9000 --no-debugger --no-reload` to run the app. - > **Note:** It is important to add `--host 0.0.0.0` when using `appPort` in `devcontainer.json` since this uses Docker to "publish" the port rather than forwarding it. It therefore will not work if the application only listens to localhost. + - Type `python -m flask run --port 9000 --no-debugger --no-reload` to run the app. - Open a local browser and go to `http://localhost:9000` to see the running app. + > **Tip:** If you use this container outside of VS Code via `docker run` with `-p 9000`, you may need to append `--host 0.0.0.0` to the command above. The `-p` option "publishes" the port rather than forwarding it. It therefore will not work if the application only listens to localhost. The `forwardPorts` property in `devcontainer.json` does not have this limitation, but you can use `appPort` to publish instead if you prefer. 3. **Build, Run, and Debug:** - Open `app.py` - Add a breakpoint (e.g. on line 9).