{"id":15111,"date":"2025-12-13T00:27:35","date_gmt":"2025-12-12T16:27:35","guid":{"rendered":"https:\/\/www.quantsnote.com\/?p=15111"},"modified":"2026-04-30T19:54:08","modified_gmt":"2026-04-30T11:54:08","slug":"deploy-jupyter-notebook-xcloud-docker","status":"publish","type":"post","link":"https:\/\/www.quantsnote.com\/en\/deploy-jupyter-notebook-xcloud-docker\/","title":{"rendered":"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy"},"content":{"rendered":"<p class=\"translation-block\">In the previous article <a href=\"https:\/\/www.quantsnote.com\/python-jupyter-notebook-digitalocean-droplet\/\" target=\"_blank\" rel=\"noreferrer noopener\">\"Python \u2013 Building a Jupyter Notebook Cloud Development Environment\" (Part 1)<\/a>, we completed the basic setup of a DigitalOcean Droplet. Following the traditional path, one would typically need to log in via SSH to manually handle Python environment variables, Virtualenv, and the tedious installation of Jupyter and firewall settings.<\/p>\n\n\n\n<p class=\"translation-block\">For quantitative traders or data scientists, having a Jupyter Notebook environment that is accessible anytime, anywhere, and has independent computing resources is a dream configuration. Especially when you need to conduct long-term <strong>options historical backtesting<\/strong>, or simply don't want heavy calculations to occupy your laptop's resources, a cloud environment is the best solution.<\/p>\n\n\n\n<p class=\"translation-block\">This is also why in our newly upgraded <a href=\"https:\/\/academy.quantsnote.com\/courses\/option-strategies\/\" target=\"_blank\" rel=\"noreferrer noopener\">\"Python Options Quantitative Trading in Action\"<\/a> course, we specifically recommend this solution for students to deploy their <strong>Strategy Lab<\/strong>.<\/p>\n\n\n\n<p>However, the traditional SSH deployment method is tedious and full of pitfalls. This article will demonstrate how to use the xCloud panel combined with Docker technology to complete the setup of a Jupyter Notebook cloud environment on a DigitalOcean host in just 20 minutes, integrating Cloudflare SSL and Nginx reverse proxy to build an efficient and secure quantitative development platform.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"env-prep\">Environment Preparation and Architecture Overview<\/h2>\n\n\n\n<p>Before starting, please confirm that you have an xCloud account and a DigitalOcean (or Vultr, Hetzner) account.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"translation-block\"><p><a href=\"https:\/\/go.quantsnote.com\/xcloud\" target=\"_blank\" rel=\"noreferrer noopener\">xCloud<\/a> Free Plan \u2192 Self-hosted 1 server, 10 sites\/apps<br><a href=\"https:\/\/m.do.co\/c\/8975de92b51d\" target=\"_blank\" rel=\"noreferrer noopener nofollow sponsored\">DigitalOcean<\/a> Free Credit \u2192 30 days, $300 USD<br><a href=\"https:\/\/go.quantsnote.com\/Vultr\" target=\"_blank\" rel=\"noreferrer noopener\">Vultr<\/a> Free Credit \u2192 2 months, $200 USD<\/p><\/p>\n<\/blockquote>\n\n\n\n<p class=\"translation-block\">This deployment uses a <strong>Docker containerization<\/strong> solution rather than installing directly on the Host OS. The reason is that xCloud is essentially a management tool optimized for WordPress and PHP applications, taking over the host's Nginx, PHP-FPM, and database settings. Installing a Python environment directly at the OS level might conflict with packages used by xCloud or even be overwritten during panel updates. Docker isolates the Jupyter environment, allowing us to enjoy the convenience of xCloud without interference.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"diagram\">Architecture Diagram<\/h3>\n\n\n\n<p>External Request (HTTPS:443) \u2192 Cloudflare (SSL) \u2192 Nginx managed by xCloud (Reverse Proxy) \u2192 Docker Container (Localhost:8888) \u2192 Jupyter Notebook<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1.webp\"><img decoding=\"async\" width=\"1200\" height=\"670\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1.webp\" alt=\"xCloud x Jupyter with Docker and Cloudflare\" class=\"wp-image-15178\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1.webp 1200w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1-300x168.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1-768x429.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1-18x10.webp 18w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step1-xcloud-commands-docker\">Step 1: Install Docker Environment via xCloud Commands<\/h2>\n\n\n\n<p>First, connect your DigitalOcean account in the xCloud backend and create a new Droplet via Create Server.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean.webp\"><img decoding=\"async\" width=\"937\" height=\"538\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean.webp\" alt=\"Connect your DigitalOcean account\" class=\"wp-image-15149\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean.webp 937w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean-300x172.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean-768x441.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Server-DigitalOcean-18x10.webp 18w\" sizes=\"(max-width: 937px) 100vw, 937px\" \/><\/a><\/figure>\n\n\n\n<p>It is recommended to choose Ubuntu 22.04 LTS or 24.04 LTS version, with at least 2GB RAM to ensure smooth Python computation.<\/p>\n\n\n\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server.webp\"><img decoding=\"async\" width=\"843\" height=\"1000\" data-id=\"15128\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server.webp\" alt=\"Create NGINX Server\" class=\"wp-image-15128\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server.webp 843w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server-253x300.webp 253w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server-768x911.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-nginx-server-10x12.webp 10w\" sizes=\"(max-width: 843px) 100vw, 843px\" \/><\/a><figcaption class=\"wp-element-caption\">Create NGINX Server<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx.webp\"><img decoding=\"async\" width=\"1000\" height=\"713\" data-id=\"15130\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx.webp\" alt=\"Server is being configured\" class=\"wp-image-15130\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx-300x214.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx-768x548.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-setup-server-nginx-18x12.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><figcaption class=\"wp-element-caption\">Server is being configured<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p class=\"translation-block\">After the server is created, a reboot is required for security updates. Then, enter the server management interface. We no longer need to open Putty or Terminal; simply click <strong>Management \u2192 Commands<\/strong> in the left menu.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1.webp\"><img decoding=\"async\" width=\"1000\" height=\"403\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1.webp\" alt=\"xCloud Commands page\" class=\"wp-image-15157\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1-300x121.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1-768x310.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-management-commands1-18x7.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"get-docker\">Execute Installation Command<\/h3>\n\n\n\n<p class=\"translation-block\">Clicking <strong>+ Run Custom Command<\/strong> will open the window below. Enter the following command in the Command content box, and the system will automatically download and install Docker:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-run-command-get-docker.webp\"><img decoding=\"async\" width=\"722\" height=\"600\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-run-command-get-docker.webp\" alt=\"Run command to get docker\" class=\"wp-image-15124\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-run-command-get-docker.webp 722w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-run-command-get-docker-300x249.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-run-command-get-docker-14x12.webp 14w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/a><\/figure>\n\n\n\n\n\n<pre title=\"Install Docker\" class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"># Install Docker\ncurl -fsSL https:\/\/get.docker.com | sh\n\n# Start and enable on boot\nsystemctl start docker\nsystemctl enable docker<\/code><\/pre>\n\n\n\n<p class=\"translation-block\">Click <strong>Run Command<\/strong>, and xCloud will send the instruction to the server. When the Status shows <code>Completed<\/code> and the Action column's View result shows no error messages, Docker is ready.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker.webp\"><img decoding=\"async\" width=\"1000\" height=\"188\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker.webp\" alt=\"Run command to get docker\" class=\"wp-image-15155\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker-300x56.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker-768x144.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-get-docker-18x3.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step2-container-for-jupyter-notebook\">Step 2: Deploy Jupyter Notebook Container<\/h2>\n\n\n\n<p>After Docker installation is complete, proceed to configure the network and storage space.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"firewall-rule\">Configure Firewall Rules<\/h3>\n\n\n\n<p class=\"translation-block\">From the left menu <strong>Security \u2192 Firewall Management<\/strong>, click Add New Rule to open Port <code>8888<\/code>. This is to ensure the system can correctly identify the communication port inside the Docker container.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-new-firewall-rule-for-jupyter.webp\"><img decoding=\"async\" width=\"702\" height=\"752\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-new-firewall-rule-for-jupyter.webp\" alt=\"add new firewall rule for Jupyter\" class=\"wp-image-15129\" style=\"width:auto;height:550px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-new-firewall-rule-for-jupyter.webp 702w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-new-firewall-rule-for-jupyter-280x300.webp 280w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-new-firewall-rule-for-jupyter-11x12.webp 11w\" sizes=\"(max-width: 702px) 100vw, 702px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"volume\">Set Up Data Persistence (Volume)<\/h3>\n\n\n\n<p class=\"translation-block\">Data resets after a container restart, so code files must be stored in the host's physical directory. Use <strong>Commands<\/strong> again to create the directory:<\/p>\n\n\n\n<pre title=\"Create Volume Directory\" class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">mkdir -p \/home\/master\/jupyter_data\nchmod 777 \/home\/master\/jupyter_data<\/code><\/pre>\n\n\n\n<p><em><em>(Note: To avoid permission issues, loose permissions are granted here temporarily. In practice, configure this based on User ID.)<\/em><\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"docker-run\">Execute Docker Run Command<\/h3>\n\n\n\n<p class=\"translation-block\">Next, create a new Command to start Jupyter. We use the official <code>jupyter\/scipy-notebook<\/code> (which includes more scientific computing packages).<\/p>\n\n\n\n<pre title=\"Run Jupyter Container\" class=\"wp-block-code\"><code class=\"\">docker run -d -p 8888:8888 --name my-jupyter -v \/home\/master\/jupyter_data:\/home\/jovyan\/work --restart unless-stopped -e JUPYTER_ENABLE_LAB=yes quay.io\/jupyter\/scipy-notebook<\/code><\/pre>\n\n\n\n<p><strong><strong>Command Parameter Analysis:<\/strong><\/strong><\/p>\n\n\n\n\n\n<ol class=\"wp-block-list\">\n<li style=\"padding-bottom:var(--wp--preset--spacing--20)\"><code>docker run<\/code><br>The basic command, meaning &#8220;<strong>Create and start a new Container from an Image<\/strong>&#8220;.<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>-d<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Meaning<\/strong>: Run in <strong>background<\/strong> (Detached Mode).<\/li>\n\n\n\n<li><strong>Effect<\/strong>: Without this parameter, the terminal screen will be occupied by Jupyter&#8217;s Log messages, and Jupyter will stop if the window is closed. With this parameter, it runs silently in the background, allowing us to continue entering other commands.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>-p 8888:8888<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Format<\/strong>: <code>&lt;Host Port&gt;:&lt;Container Internal Port&gt;<\/code><\/li>\n\n\n\n<li><strong>Meaning<\/strong>: Map the server&#8217;s external Port to the container&#8217;s internal Port (Port Mapping).<\/li>\n\n\n\n<li><strong>Effect<\/strong>:\n<ul class=\"wp-block-list\">\n<li><strong>Left 8888<\/strong>: The port opened to the outside on the xCloud host (Nginx forwards traffic here).<\/li>\n\n\n\n<li><strong>Right 8888<\/strong>: The port Jupyter program listens to by default inside the container.<\/li>\n\n\n\n<li><em><em><strong>Application<\/strong>: If you want to run two Jupyters on the same machine, the second one can be changed to <code>-p 8889:8888<\/code>.<\/em><\/em><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>--name my-jupyter<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Meaning<\/strong>: Name the container for easier management.<\/li>\n\n\n\n<li><strong>Effect<\/strong>: If unnamed, Docker assigns a random code. Naming it allows convenient management commands like <code>docker stop my-jupyter<\/code> or <code>docker logs my-jupyter<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>-v \/home\/master\/jupyter_data:\/home\/jovyan\/work<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Format<\/strong>: <code>&lt;Host Real Path&gt;:&lt;Container Internal Path&gt;<\/code><\/li>\n\n\n\n<li><strong>Meaning<\/strong>: Directly &#8220;mount&#8221; (map) a folder from the server&#8217;s hard drive into the container.<\/li>\n\n\n\n<li><strong>Effect<\/strong>: Set up data persistence; since data resets on container restart, this is key to <strong>data preservation<\/strong>!\n<ul class=\"wp-block-list\">\n<li><strong>Left <code>\/home\/master\/jupyter_data<\/code><\/strong>: The actual folder on the xCloud host. All <code>.ipynb<\/code> code files will physically exist here.<\/li>\n\n\n\n<li><strong>Right <code>\/home\/jovyan\/work<\/code><\/strong>: The default working directory seen inside the Jupyter container (<code>jovyan<\/code> is the default username in the Jupyter Docker image).<\/li>\n\n\n\n<li><strong>Result<\/strong>: Even if you delete and recreate this Docker container, as long as <code>\/home\/master\/jupyter_data<\/code> exists on the host, previously saved code will not be lost.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>--restart unless-stopped<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Meaning<\/strong>: Ensure Jupyter automatically restarts after a server reboot or Docker crash.<\/li>\n\n\n\n<li><strong>Effect<\/strong>: Tells the Docker daemon to try restarting this container automatically unless it was manually stopped using <code>docker stop<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>-e JUPYTER_ENABLE_LAB=yes<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Effect<\/strong>: Use the newer <strong>JupyterLab<\/strong> interface (IDE-like, with file explorer, tabs) by default upon startup, instead of the old Jupyter Notebook interface.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li style=\"padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--20)\"><code>quay.io\/jupyter\/scipy-notebook<\/code>\n<ul class=\"wp-block-list\">\n<li><strong>Meaning<\/strong>: Specify the Image Source.<\/li>\n\n\n\n<li style=\"padding-top:0;padding-bottom:0\"><strong>Detail<\/strong>:\n<ul class=\"wp-block-list\">\n<li style=\"padding-top:0;padding-bottom:0\"><code>quay.io<\/code>: The image Registry, similar to GitHub.<\/li>\n\n\n\n<li style=\"padding-top:0;padding-bottom:0\"><code>jupyter\/scipy-notebook<\/code>: The officially maintained image version. Besides the basic Python environment, it comes pre-installed with common scientific computing packages like Pandas, NumPy, SciPy, and Matplotlib, saving extra <code>pip install<\/code> time.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p>After execution, verify that the Status displays Completed.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run.png\"><img decoding=\"async\" width=\"1033\" height=\"148\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run.png\" alt=\"Execute docker run command\" class=\"wp-image-15156\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run.png 1033w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run-300x43.png 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run-768x110.png 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-run-18x3.png 18w\" sizes=\"(max-width: 1033px) 100vw, 1033px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step3-blank-site-and-cloudflare-ssl\">Step 3: Create Blank Site and Cloudflare SSL Setup<\/h2>\n\n\n\n<p class=\"translation-block\">Jupyter uses HTTP by default and runs on port 8888; directly exposing the IP and port is neither secure nor professional. We will use xCloud's <strong>Blank Site<\/strong> to handle domain resolution and SSL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"xcloud-blank-site\">Create a Blank Website in xCloud<\/h3>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li class=\"translation-block\">Switch to the <strong>Site List<\/strong> tab and click <strong>+ New Site<\/strong>.<\/li>\n\n\n\n<li class=\"translation-block\">Select <strong>Custom PHP \u2192 Blank Site<\/strong> (do not install sites containing applications).<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site.webp\"><img decoding=\"async\" width=\"1000\" height=\"359\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site.webp\" alt=\"Add a new Blank Site\" class=\"wp-image-15114\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site-300x108.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site-768x276.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-add-new-site-blank-site-18x6.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>Select <strong>Setup into a New Domain<\/strong>\n<ul class=\"wp-block-list\">\n<li><strong>New Site Title<\/strong>: Enter the website name (e.g., <code>jupyter-app<\/code>).<\/li>\n\n\n\n<li><strong>Domain Name<\/strong>: Enter the subdomain you want to use, such as <code>jupyter.domain.com<\/code>.<\/li>\n\n\n\n<li><strong>Add DNS and SSL Certificate on Cloudflare<\/strong>: Enable this option for xCloud to complete DNS and SSL configuration directly via API on Cloudflare.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl.webp\"><img decoding=\"async\" width=\"798\" height=\"1000\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl.webp\" alt=\"Configure DNS and SSL for Blank site\" class=\"wp-image-15127\" style=\"width:auto;height:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl.webp 798w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl-239x300.webp 239w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl-768x962.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-setup-dns-and-ssl-10x12.webp 10w\" sizes=\"(max-width: 798px) 100vw, 798px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li class=\"translation-block\">Select No Database for <strong>Database<\/strong>. Keep the PHP version and Web Root as default; Nginx will forward the traffic and won't read this directory.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection.webp\"><img decoding=\"async\" width=\"865\" height=\"1000\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection.webp\" alt=\"configuration and DB connection\" class=\"wp-image-15117\" style=\"width:auto;height:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection.webp 865w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection-260x300.webp 260w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection-768x888.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-config-and-db-connection-10x12.webp 10w\" sizes=\"(max-width: 865px) 100vw, 865px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li>Confirm everything is correct and start creation; deployment takes about two minutes.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed.webp\"><img decoding=\"async\" width=\"984\" height=\"493\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed.webp\" alt=\"The blank site deployed successfully\" class=\"wp-image-15115\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed.webp 984w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed-300x150.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed-768x385.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-blank-site-deployed-18x9.webp 18w\" sizes=\"(max-width: 984px) 100vw, 984px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"cloudflare-integration\">Cloudflare Integration and Automated HTTPS Issuance<\/h3>\n\n\n\n<p>This is one of the greatest conveniences brought by xCloud.<\/p>\n\n\n\n<p class=\"translation-block\">In the Site Dashboard left menu, select <strong>Domain \u2192 SSL\/HTTPS<\/strong>. If Cloudflare API integration is set up, the system automatically issues an Origin Certificate and enforces HTTPS redirection.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare.webp\"><img decoding=\"async\" width=\"1000\" height=\"423\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare.webp\" alt=\"Cloudflare integration\" class=\"wp-image-15146\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare-300x127.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare-768x325.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Domain-SSL-HTTPS-by-Cloudflare-18x8.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<p class=\"translation-block\">At this point, visiting <code>https:\/\/jupyter.domain.com<\/code> will show a 403 Forbidden error. This means the SSL and Nginx basic connections are working, and only the reverse proxy needs to be configured.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step4-nginx-reverse-proxy\">Step 4: Configure Nginx Reverse Proxy<\/h2>\n\n\n\n<p class=\"translation-block\">We need to modify the Blank Site's Nginx settings to forward all traffic to <code>localhost:8888<\/code>.<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li class=\"translation-block\">Select <strong>Tools \u2192 Nginx Customization<\/strong> in the Site Dashboard.<\/li>\n\n\n\n<li class=\"translation-block\">Click <strong>Add a New Config<\/strong>, and select <strong>Inside Server Block<\/strong> for the Config Type location.<\/li>\n\n\n\n<li class=\"translation-block\">Since xCloud currently doesn't provide a blank Nginx config, enter the following Nginx rule using Regex (<code>~<\/code>) to overwrite the default path:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy.webp\"><img decoding=\"async\" width=\"873\" height=\"950\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy.webp\" alt=\"custom rule for nginx reverse proxy\" class=\"wp-image-15167\" style=\"width:auto;height:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy.webp 873w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy-276x300.webp 276w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy-768x836.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-custom-nginx-config-for-reverse-proxy-11x12.webp 11w\" sizes=\"(max-width: 873px) 100vw, 873px\" \/><\/a><\/figure>\n\n\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"nginx\" class=\"language-nginx\">location ~ ^\/ {\n    proxy_pass http:\/\/127.0.0.1:8888;\n\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"upgrade\";\n\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n\n    client_max_body_size 100M;\n    proxy_read_timeout 86400;\n}<\/code><\/pre>\n\n\n\n<p><strong><strong>Key Configuration Explanation:<\/strong><\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"translation-block\"><strong>WebSocket Support<\/strong>: Jupyter Notebook operation relies on WebSockets to maintain Kernel connections. The <code>Upgrade<\/code> and <code>Connection<\/code> headers must be added; otherwise, the Notebook will open but cannot execute code (Kernel Disconnected).<\/li>\n\n\n\n<li class=\"translation-block\"><strong>Proxy Pass<\/strong>: Points to the local port 8888 mapped by Docker.<\/li>\n<\/ul>\n\n\n\n<p class=\"translation-block\">Click <strong>Run &amp; Debug<\/strong> to test the syntax. If there are no errors, click <strong>Save Config<\/strong>, and the system will automatically restart the Nginx service.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step5-token-and-get-started\">Step 5: Get Login Token and Test Development<\/h2>\n\n\n\n<p class=\"translation-block\">Open your browser and visit <code>https:\/\/jupyter.domain.com<\/code>. You should see the Jupyter login screen requesting a Password or Token.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-login.webp\"><img decoding=\"async\" width=\"599\" height=\"912\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-login.webp\" alt=\"jupyter login page\" class=\"wp-image-15123\" style=\"width:auto;height:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-login.webp 599w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-login-197x300.webp 197w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-Jupyter-login-8x12.webp 8w\" sizes=\"(max-width: 599px) 100vw, 599px\" \/><\/a><\/figure>\n\n\n\n<p>Since this is the first launch, you need to retrieve the default Token from the Docker Log.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"access-token\">Retrieve Access Token via Logs<\/h3>\n\n\n\n<p class=\"translation-block\">Return to <strong>Management \u2192 Commands<\/strong> in the server management interface and create a query command:<\/p>\n\n\n\n<pre title=\"Get Jupyter Token\" class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">docker logs my-jupyter 2&gt;&amp;1 | grep \"token=\"<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs.webp\"><img decoding=\"async\" width=\"1000\" height=\"106\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs.webp\" alt=\"retrieve access token via logs\" class=\"wp-image-15153\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-300x32.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-768x81.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-18x2.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<p class=\"translation-block\">In the execution result, copy the long code following <code>token=<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-for-token.webp\"><img decoding=\"async\" width=\"652\" height=\"323\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-for-token.webp\" alt=\"the token info in docker logs\" class=\"wp-image-15154\" style=\"object-fit:cover\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-for-token.webp 652w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-for-token-300x149.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-command-docker-logs-for-token-18x9.webp 18w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"setup-a-password\">Set Password and Start Using<\/h3>\n\n\n\n<p>Return to the browser and paste the Token into the login box. For easier future logins, it is recommended to set a fixed password in the \"Setup a Password\" field below.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-Setup-a-Password.webp\"><img decoding=\"async\" width=\"599\" height=\"350\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-Setup-a-Password.webp\" alt=\"setup a password for Jupyter Notebook\/Jupyter Lab\" class=\"wp-image-15194\" style=\"object-fit:cover\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-Setup-a-Password.webp 599w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-Setup-a-Password-300x175.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-Setup-a-Password-18x12.webp 18w\" sizes=\"(max-width: 599px) 100vw, 599px\" \/><\/a><\/figure>\n\n\n\n<p class=\"translation-block\">After successful login, you will see the <code>\/work<\/code> directory. Try creating a new Python 3 Notebook, enter <code>print(\"Hello Quants Note\")<\/code>, and execute. If the result outputs successfully, the WebSocket connection is normal, and the environment deployment is complete.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab.png\"><img decoding=\"async\" width=\"1135\" height=\"820\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab.png\" alt=\"Jupyter Notebook \/ JupyterLab\" class=\"wp-image-15160\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab.png 1135w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-300x217.png 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-768x555.png 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-JupyterLab-18x12.png 18w\" sizes=\"(max-width: 1135px) 100vw, 1135px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step6-performance-and-routine-maintenance\">Step 6: Performance Tuning and Routine Maintenance<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"disable-services\">Disable Unnecessary Services to Save Memory<\/h3>\n\n\n\n<p class=\"translation-block\">If you are using a host with lower specifications, don't forget to disable services that are not used in this technical architecture. From the left menu <strong>Management<\/strong> <strong>\u2192<\/strong> <strong>Settings<\/strong>, in the service list, click the <strong>Disable<\/strong> button under Action for any unnecessary services.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable.png\"><img decoding=\"async\" width=\"1266\" height=\"437\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable.png\" alt=\"xCloud disable unnecessary services to save host resources\" class=\"wp-image-15527\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable.png 1266w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable-300x104.png 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable-768x265.png 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-settings-service-disable-18x6.png 18w\" sizes=\"(max-width: 1266px) 100vw, 1266px\" \/><\/a><\/figure>\n\n\n\n<p>Following our steps, the services that can be disabled include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"translation-block\"><strong>MariaDB (Database)<\/strong>: One of the significant memory consumers; it typically uses over 100MB of RAM even when idle.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>Redis (Cache)<\/strong>: Redis is used to cache data in memory to speed up website loading (Object Cache). For a real-time computing environment like Jupyter, or a simple reverse proxy, it will only consume extra RAM.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>Supervisor<\/strong>: Usually used to manage PHP background queues (Queue Workers), such as sending emails or processing large images. If only running Jupyter, this service is redundant.<\/li>\n<\/ul>\n\n\n\n<p>Overall, this can free up about 130MB of memory and a small amount of CPU resources.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"add-cronjobs\">Set Up Cron Jobs to Manage Docker<\/h3>\n\n\n\n<p class=\"translation-block\">From the left menu <strong>Management<\/strong> <strong>\u2192<\/strong> <strong>Cron Jobs<\/strong>, click the <strong>+ Add Cron Job<\/strong> button to add two automated scheduled tasks.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"translation-block\">Automatically restart the Jupyter container every Monday at 4:00 AM (to free up memory and solve host performance issues)<br><code>0 4 * * 1 docker restart my-jupyter<\/code><\/li>\n\n\n\n<li class=\"translation-block\">Automatically clean up unused Docker junk every Monday at 4:00 AM (to prevent storage space from gradually shrinking)<br><code>5 4 * * 1 docker system prune -f<\/code><\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><a href=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker.webp\"><img decoding=\"async\" width=\"1000\" height=\"215\" src=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker.webp\" alt=\"xCloud add cronjobs to restart Jupyter container and clean up unused Docker data\" class=\"wp-image-15528\" style=\"width:650px\" title=\"xCloud Deployment in Action: Jupyter Notebook with Docker, Cloudflare, and Nginx Reverse Proxy\" srcset=\"https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker.webp 1000w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker-300x65.webp 300w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker-768x165.webp 768w, https:\/\/www.quantsnote.com\/wp-content\/uploads\/2026\/01\/xCloud-management-cronjobs-restart-docker-18x4.webp 18w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"performance\">Deployment Efficiency and Time Cost Analysis<\/h2>\n\n\n\n<p>Compared to traditional manual SSH configuration (installing Python, Virtualenv, Nginx Config, Certbot SSL), the solution using xCloud combined with Docker significantly improves efficiency. Here is the time cost breakdown for this practice:<\/p>\n\n\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th class=\"has-text-align-center\" data-align=\"center\">Deployment Stage<\/th><th class=\"has-text-align-center\" data-align=\"center\">Estimated Time<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">Host &amp; Docker Initialization<\/td><td class=\"has-text-align-center\" data-align=\"center\">10 Mins<\/td><td>Includes Droplet creation, system updates, and automated Docker installation<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Container Deployment<\/td><td class=\"has-text-align-center\" data-align=\"center\">5 Mins<\/td><td>Downloading Image and starting Jupyter, no compilation or dependency handling needed<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Site &amp; SSL Config<\/td><td class=\"has-text-align-center\" data-align=\"center\">3 Mins<\/td><td>xCloud automatically handles DNS resolution and Cloudflare certificates<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Nginx Reverse Proxy<\/td><td class=\"has-text-align-center\" data-align=\"center\">2 Mins<\/td><td>Applying the pre-configured Config template<\/td><\/tr><\/tbody><tfoot><tr><td class=\"has-text-align-center\" data-align=\"center\">Total Time<\/td><td class=\"has-text-align-center\" data-align=\"center\">Approx. 20 Mins<\/td><td><strong>Saves about 60% of time compared to manual deployment<\/strong><\/td><\/tr><\/tfoot><\/table><\/figure>\n\n\n\n<p>This workflow standardizes tedious system management, allowing quantitative traders to reserve their core energy for strategy development rather than environment maintenance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"next-step\">\ud83d\udca1 Environment Setup Complete, What's Next?<\/h2>\n\n\n\n<p>With a powerful cloud computing environment, you have completed the first piece of the quantitative trading puzzle. Next, you need proven strategy logic and backtesting tools.<\/p>\n\n\n\n<p class=\"translation-block\">If you don't want to write code from scratch, we invite you to join our <strong>\"Python Options Quantitative Trading in Action: From Strategy Principles to Visual Backtesting\"<\/strong> course.<\/p>\n\n\n\n<p>In the newly added chapters of this course, we directly provide:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"translation-block\"><strong>Complete <code>BacktestEngine<\/code> Source Code<\/strong>: Includes data caching and daily P&amp;L settlement features.<\/li>\n\n\n\n<li class=\"translation-block\"><strong>3D Risk Visualization Dashboard<\/strong>: Allows you to analyze strategies in real-time via sliders within Jupyter Notebook.<\/li>\n<\/ul>\n\n\n\n<p class=\"translation-block\">You can directly upload the <strong>Python Strategy Lab<\/strong> files provided in the course to your newly set up xCloud Jupyter Notebook, and immediately start backtesting assets like SPY and NVDA to validate your trading ideas!<\/p>\n\n\n\n<p class=\"translation-block\">\ud83d\udc49 <strong><a href=\"https:\/\/academy.quantsnote.com\/courses\/option-strategies\/\" target=\"_blank\" rel=\"noreferrer noopener\">Click here for course details and limited-time offers<\/a><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>Through the practical walkthrough in this article, we have successfully simplified complex server maintenance work into a standardized Docker deployment workflow. This architecture is not only suitable for Jupyter Notebook, but in the future, you can also use the same logic to deploy quantitative trading bots or market monitoring dashboards.<\/p>\n\n\n\n<p>We hope this article helps you clear the obstacles of environment setup and immediately start your quantitative development journey.<\/p>","protected":false},"excerpt":{"rendered":"<p>Skip the tedious SSH setup! Deploy a production-ready Jupyter Notebook \/ JupyterLab environment in just 20 minutes with xCloud, Docker, and Cloudflare. The perfect cloud architecture for quantitative traders to focus on strategy, not maintenance.<\/p>","protected":false},"author":1,"featured_media":15178,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gspb_post_css":"","_surecart_dashboard_logo_width":"180px","_surecart_dashboard_show_logo":true,"_surecart_dashboard_navigation_orders":true,"_surecart_dashboard_navigation_invoices":true,"_surecart_dashboard_navigation_subscriptions":true,"_surecart_dashboard_navigation_downloads":true,"_surecart_dashboard_navigation_billing":true,"_surecart_dashboard_navigation_account":true,"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","footnotes":""},"categories":[5,44],"tags":[205,287,206,284,260,286,285],"class_list":["post-15111","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","category-quantitative-analysis","tag-digitalocean","tag-docker","tag-jupyter-notebook","tag-nginx-reverse-proxy","tag-xcloud","tag-devops-automation","tag-cloud-development-environment"],"blocksy_meta":[],"taxonomy_info":{"category":[{"value":5,"label":"\u7a0b\u5f0f\u8a2d\u8a08"},{"value":44,"label":"\u8a08\u91cf\u5206\u6790"}],"post_tag":[{"value":205,"label":"DigitalOcean"},{"value":287,"label":"Docker"},{"value":206,"label":"Jupyter Notebook"},{"value":284,"label":"Nginx \u53cd\u5411\u4ee3\u7406"},{"value":260,"label":"xCloud"},{"value":286,"label":"\u81ea\u52d5\u5316\u904b\u7dad"},{"value":285,"label":"\u96f2\u7aef\u958b\u767c\u74b0\u5883"}]},"featured_image_src_large":["https:\/\/www.quantsnote.com\/wp-content\/uploads\/2025\/12\/xCloud-x-Jupyter-with-Docker-and-Cloudflare_1.webp",1200,670,false],"author_info":{"display_name":"Steven Tseng","author_link":"https:\/\/www.quantsnote.com\/en\/author\/feng-yin\/"},"comment_info":0,"category_info":[{"term_id":5,"name":"\u7a0b\u5f0f\u8a2d\u8a08","slug":"programming","term_group":0,"term_taxonomy_id":5,"taxonomy":"category","description":"\u5728\u7a0b\u5f0f\u8a2d\u8a08\u7684\u6587\u7ae0\u4e2d\uff0c\u900f\u904e Python \u5728\u91d1\u878d\u9818\u57df\u3001\u8a08\u91cf\u5206\u6790\u3001\u8ca1\u52d9\u5de5\u7a0b\u4e0a\u7684\u61c9\u7528\uff0c\u8b93\u5927\u5bb6\u77e5\u9053\u5982\u4f55\u5be6\u4f5c\u91d1\u878d\u5546\u54c1\u5b9a\u50f9\u3001\u98a8\u96aa\u8a08\u7b97\u3001\u98a8\u96aa\u8996\u5716\u7e6a\u88fd\uff0c\u4ee5\u53ca\u8907\u96dc\u6295\u8cc7\u7d44\u5408\u7684\u640d\u76ca\u5206\u6790\uff1b\u6b64\u5916\uff0c\u4e5f\u5305\u62ec\u5982\u4f55\u63d0\u5347\u6548\u7387\u7684\u904b\u7b97\u6280\u5de7\u3002","parent":0,"count":7,"filter":"raw","cat_ID":5,"category_count":7,"category_description":"\u5728\u7a0b\u5f0f\u8a2d\u8a08\u7684\u6587\u7ae0\u4e2d\uff0c\u900f\u904e Python \u5728\u91d1\u878d\u9818\u57df\u3001\u8a08\u91cf\u5206\u6790\u3001\u8ca1\u52d9\u5de5\u7a0b\u4e0a\u7684\u61c9\u7528\uff0c\u8b93\u5927\u5bb6\u77e5\u9053\u5982\u4f55\u5be6\u4f5c\u91d1\u878d\u5546\u54c1\u5b9a\u50f9\u3001\u98a8\u96aa\u8a08\u7b97\u3001\u98a8\u96aa\u8996\u5716\u7e6a\u88fd\uff0c\u4ee5\u53ca\u8907\u96dc\u6295\u8cc7\u7d44\u5408\u7684\u640d\u76ca\u5206\u6790\uff1b\u6b64\u5916\uff0c\u4e5f\u5305\u62ec\u5982\u4f55\u63d0\u5347\u6548\u7387\u7684\u904b\u7b97\u6280\u5de7\u3002","cat_name":"\u7a0b\u5f0f\u8a2d\u8a08","category_nicename":"programming","category_parent":0},{"term_id":44,"name":"\u8a08\u91cf\u5206\u6790","slug":"quantitative-analysis","term_group":0,"term_taxonomy_id":44,"taxonomy":"category","description":"\u8a08\u91cf\u5206\u6790\u3001\u8ca1\u52d9\u5de5\u7a0b\u9818\u57df\u76f8\u7576\u7684\u5ee3\u6cdb\uff0c\u6709\u4eba\u7814\u7a76\u6700\u4f73\u5316\u6295\u8cc7\u7d44\u5408\u7684\u5efa\u7acb\u6a21\u5f0f\uff0c\u6709\u4eba\u7814\u7a76\u5e02\u5834\u5fae\u7d50\u69cb\uff0c\u8a66\u5716\u5f9e\u5bc6\u96c6\u7684\u8cc7\u8a0a\u4e2d\u627e\u51fa\u5e02\u5834\u898f\u5f8b\u6027\uff0c\u66f4\u6709\u4eba\u81f4\u529b\u65bc\u57fa\u790e\u7406\u8ad6\u3001\u6a21\u578b\u7684\u5efa\u7acb\u3002","parent":0,"count":17,"filter":"raw","cat_ID":44,"category_count":17,"category_description":"\u8a08\u91cf\u5206\u6790\u3001\u8ca1\u52d9\u5de5\u7a0b\u9818\u57df\u76f8\u7576\u7684\u5ee3\u6cdb\uff0c\u6709\u4eba\u7814\u7a76\u6700\u4f73\u5316\u6295\u8cc7\u7d44\u5408\u7684\u5efa\u7acb\u6a21\u5f0f\uff0c\u6709\u4eba\u7814\u7a76\u5e02\u5834\u5fae\u7d50\u69cb\uff0c\u8a66\u5716\u5f9e\u5bc6\u96c6\u7684\u8cc7\u8a0a\u4e2d\u627e\u51fa\u5e02\u5834\u898f\u5f8b\u6027\uff0c\u66f4\u6709\u4eba\u81f4\u529b\u65bc\u57fa\u790e\u7406\u8ad6\u3001\u6a21\u578b\u7684\u5efa\u7acb\u3002","cat_name":"\u8a08\u91cf\u5206\u6790","category_nicename":"quantitative-analysis","category_parent":0}],"tag_info":[{"term_id":205,"name":"DigitalOcean","slug":"digitalocean","term_group":0,"term_taxonomy_id":205,"taxonomy":"post_tag","description":"DigitalOcean \u96f2\u7aef\u4e3b\u6a5f Droplets","parent":0,"count":3,"filter":"raw"},{"term_id":287,"name":"Docker","slug":"docker","term_group":0,"term_taxonomy_id":287,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":206,"name":"Jupyter Notebook","slug":"jupyter-notebook","term_group":0,"term_taxonomy_id":206,"taxonomy":"post_tag","description":"Jupyter Notebook \u7a0b\u5f0f\u958b\u767c\u7684\u6574\u5408\u67b6\u69cb","parent":0,"count":2,"filter":"raw"},{"term_id":284,"name":"Nginx \u53cd\u5411\u4ee3\u7406","slug":"nginx-reverse-proxy","term_group":0,"term_taxonomy_id":284,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw"},{"term_id":260,"name":"xCloud","slug":"xcloud","term_group":0,"term_taxonomy_id":260,"taxonomy":"post_tag","description":"","parent":0,"count":4,"filter":"raw"},{"term_id":286,"name":"\u81ea\u52d5\u5316\u904b\u7dad","slug":"devops-automation","term_group":0,"term_taxonomy_id":286,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":285,"name":"\u96f2\u7aef\u958b\u767c\u74b0\u5883","slug":"cloud-development-environment","term_group":0,"term_taxonomy_id":285,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"}],"_links":{"self":[{"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/posts\/15111","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/comments?post=15111"}],"version-history":[{"count":2,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/posts\/15111\/revisions"}],"predecessor-version":[{"id":16782,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/posts\/15111\/revisions\/16782"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/media\/15178"}],"wp:attachment":[{"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/media?parent=15111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/categories?post=15111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.quantsnote.com\/en\/wp-json\/wp\/v2\/tags?post=15111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}