{"id":18123318,"url":"https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap","last_synced_at":"2025-10-23T20:32:51.692Z","repository":{"id":72596173,"uuid":"61927828","full_name":"jay-johnson/docker-nginx-sphinx-bootstrap","owner":"jay-johnson","description":"Host your own Technical Blog with Docker + nginx + Sphinx Bootstrap","archived":false,"fork":false,"pushed_at":"2016-07-14T02:44:29.000Z","size":26,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-12T18:51:29.806Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jay-johnson.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-25T05:02:27.000Z","updated_at":"2022-08-22T21:29:15.000Z","dependencies_parsed_at":"2023-05-24T15:15:16.163Z","dependency_job_id":null,"html_url":"https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Fdocker-nginx-sphinx-bootstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Fdocker-nginx-sphinx-bootstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Fdocker-nginx-sphinx-bootstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Fdocker-nginx-sphinx-bootstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jay-johnson","download_url":"https://codeload.github.com/jay-johnson/docker-nginx-sphinx-bootstrap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247485253,"owners_count":20946398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-01T07:09:15.926Z","updated_at":"2025-10-23T20:32:51.624Z","avatar_url":"https://github.com/jay-johnson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"===================================================================\nHost Your Own Technical Blog with Docker + nginx + Sphinx Bootstrap\n===================================================================\n\n.. figure:: http://jaypjohnson.com/_images/image_homepagesample.png\n\n   Sample screenshot from a new deployment\n\nI built this repository_ for hosting my own technical blog + resume + work portfolio. It uses `docker compose`_ to deploy my nginx_ and sphinx-bootstrap_ containers and shares a mounted volume across the two containers. \n\nI use this repository for hosting:\n\nhttp://jaypjohnson.com\n\nDocker Hub Image(s): `jayjohnson/nginx`_ and `jayjohnson/sphinx-bootstrap`_\n\nContainer Repo(s): docker-nginx_ and docker-sphinx-bootstrap_ \n\nDate: **2016-06-25**\n\n.. role:: bash(code)\n      :language: bash\n\nOverview\n--------\n\nI built this composition for hosting a nice-to-read blog that made it easy to generate content instead of battling formatting. Now I can write a post using `reStructuredText Markup`_ and the `python Sphinx bootstrap`_ documentation tooling converts each ``rst`` file into readable, static html which is hosted using the nginx_ container for HTTP traffic on port 80 (or 443) to the static html files. Once I containerized the sphinx-bootstrap-theme_ I added automatic integration with `Google Analytics`_ + `Google Search Console`_ for others looking to do the same thing. I like that out-of-the-box the sphinx-bootstrap-theme_ comes with support for `multiple bootswatch themes`_ and there are even more themes available from the `bootswatch repository`_ and `bootswatch website`_. Additionally it is nice to know that this blog is already mobile-ready because it is built using `bootstrap`_.\n\nIntegrating with Google Analytics\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. Set your `Google Analytics Tracking Code`_ to the ENV_GOOGLE_ANALYTICS_CODE_ environment variable before container creation\n\n   During container startup the environment variable ``ENV_GOOGLE_ANALYTICS_CODE`` will be `automatically installed into the default html layout`_ on every page across your site\n\nIntegrating with Google Search Console\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. Automatic **sitemap.xml** creation\n\n   When the container starts or you `manually rebuild the html content`_ it will `automatically build`_ a ``sitemap.xml`` from any files ending with a ``.rst`` extension in the repository's root directory. This file is stored in the environment variable ``ENV_DOC_OUTPUT_DIR`` directory. This is handy when you want to integrate your site into the `Google Search Console`_ and it should look similar to: http://jaypjohnson.com/sitemap.xml\n\nWhat can I use it for?\n~~~~~~~~~~~~~~~~~~~~~~\n\nAfter working with the `Levvel team`_ over the past year, I realized the importance of having a blog to demonstrate technical expertise. After watching wordpress lose my work, I knew there had to be a better way. Recently, my friend `Alex Smith`_ recommended I check out `Sphinx`_ because it made documentation even easier than traditional markdown. After finding the `python Sphinx bootstrap`_ repository I knew I wanted to drop this into a docker container so I could deploy content while keeping the nginx services up and running.\n\nI now use this repository as `my blog`_ for `technical posts`_, hosting my `projects and stack discussions`_, `work history`_, resume_, and `contact information`_. I find it so much easier to write an ``rst`` file and let the framework translate it into formatted, stylized html. Now I can focus on content instead of the presentation (which is nice because I am not a web developer or artist). \n\nOther interesting out-of-the-box features are:\n\n* A native ``Search`` bar on each page\n* Each page has a ``Source`` button in the navigation bar to quickly inspect the original ``rst`` markup data \n\n.. _docker compose: https://docs.docker.com/compose/\n.. _Google Analytics: https://analytics.google.com/\n.. _Google Search Console: https://www.google.com/webmasters/tools/\n.. _Levvel team: http://levvel.io\n.. _Alex Smith: https://github.com/ajsmith\n.. _Sphinx: http://www.sphinx-doc.org/en/stable/\n.. _reStructuredText Markup: http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html\n.. _python Sphinx bootstrap: https://github.com/ryan-roemer/sphinx-bootstrap-theme\n.. _sphinx-bootstrap-theme: https://github.com/ryan-roemer/sphinx-bootstrap-theme\n.. _multiple bootswatch themes: https://github.com/ryan-roemer/sphinx-bootstrap-theme/blob/bfb28af310ad5082fae01dc1ff08dab6ab3fa410/demo/source/conf.py#L146-L150\n.. _bootswatch website: http://bootswatch.com/\n.. _bootswatch repository: https://github.com/thomaspark/bootswatch\n.. _bootstrap: http://getbootstrap.com/\n.. _Google Analytics Tracking Code: https://support.google.com/analytics/answer/1008080?hl=en\n.. _ENV_GOOGLE_ANALYTICS_CODE: https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap/blob/db0f1f944918a0c8a0e1c2c6593cde6f01a173f1/docker-compose.yml#L24\n.. _automatically installed into the default html layout: https://github.com/jay-johnson/docker-sphinx-bootstrap/blob/2a752b96a7bcd378dbb207da1922c2e8997dc7ae/containerfiles/start-container.sh#L13-L14\n.. _manually rebuild the html content: https://github.com/jay-johnson/docker-sphinx-bootstrap/blob/2a752b96a7bcd378dbb207da1922c2e8997dc7ae/containerfiles/start-container.sh#L16-17\n.. _automatically build: https://github.com/jay-johnson/docker-sphinx-bootstrap/blob/2a752b96a7bcd378dbb207da1922c2e8997dc7ae/containerfiles/start-container.sh#L21-L41\n.. _my blog: http://jaypjohnson.com\n.. _technical posts : http://jaypjohnson.com/2016-06-24-configurable-docker-nginx.html\n.. _projects and stack discussions: http://jaypjohnson.com/redis.html\n.. _resume: http://jaypjohnson.com/_downloads/JayJohnson-Resume.pdf\n.. _work history : http://jaypjohnson.com/work_history.html\n.. _contact information: http://jaypjohnson.com/contact.html\n.. _repository: https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap\n.. _nginx : https://hub.docker.com/r/jayjohnson/nginx/\n.. _sphinx-bootstrap : https://hub.docker.com/r/jayjohnson/sphinx-bootstrap\n.. _jayjohnson/nginx : https://hub.docker.com/r/jayjohnson/nginx/\n.. _jayjohnson/sphinx-bootstrap : https://hub.docker.com/r/jayjohnson/sphinx-bootstrap\n.. _start_container.sh: https://github.com/jay-johnson/docker-nginx/blob/master/containerfiles/start-container.sh\n.. _base nginx.conf : https://github.com/jay-johnson/docker-nginx/blob/master/containerfiles/base_nginx.conf\n.. _derived nginx.conf : https://github.com/jay-johnson/docker-nginx/blob/master/containerfiles/derived_nginx.conf\n.. _properties.sh : https://github.com/jay-johnson/docker-nginx/blob/master/properties.sh\n.. _docker-compose.yml: https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap/blob/master/docker-compose.yml\n.. _docker-sphinx-bootstrap: https://github.com/jay-johnson/docker-sphinx-bootstrap\n.. _docker-nginx: https://github.com/jay-johnson/docker-nginx\n.. _deploy + rebuild script: https://github.com/jay-johnson/docker-sphinx-bootstrap/blob/2a752b96a7bcd378dbb207da1922c2e8997dc7ae/containerfiles/deploy-new-content.sh\n\n\nInstall and Setup\n-----------------\n\nI am running the docker containers on an Amazon EC2 t1.micro with a Route 53 dns alias record set to route ``jaypjohnson.com`` traffic to the micro.\n\nOn the EC2 micro I ran these commands to setup and deploy the site:\n\n#. Create the ``/opt/blog`` directory\n\n   ::\n\n       $ mkdir -p /opt/blog/ \u0026\u0026 chmod 777 /opt/blog\n\n#. Clone this repo\n\n   ::\n\n       $ cd /opt/blog\n       $ git clone https://github.com/jay-johnson/docker-nginx-sphinx-bootstrap.git repo \n       $ cd repo\n       $\n\n#. Start the composition\n\n   ::\n\n       $ ./start_composition.sh\n       Creating websphinx\n       Creating webnginx\n       Done\n       $\n\n#. Test the blog\n\n   ::\n\n       $ curl -s http://localhost:80 | grep Welcome | grep h2\n       \u003ch2\u003eWelcome\u003ca class=\"headerlink\" href=\"#welcome\" title=\"Permalink to this headline\"\u003e¶\u003c/a\u003e\u003c/h2\u003e\n       $\n\nCompose Environment Variables\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can use the following environment variables inside the docker-compose.yml_ file to configure the container startup behaviors:\n\n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| Variable Name                          | Purpose                                                            | Default Value                                               | \n+========================================+====================================================================+=============================================================+ \n| **ENV_BASE_NGINX_CONFIG**              | Provide a path to a `base nginx.conf`_                             | /root/containerfiles/base_nginx.conf                        | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_DERIVED_NGINX_CONFIG**           | Provide a path to a `derived nginx.conf`_                          | /root/containerfiles/derived_nginx.conf                     | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_DEFAULT_ROOT_VOLUME**            | Path to shared volume for static html, js, css, images, and assets | /opt/blog                                                   | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_DOC_SOURCE_DIR**                 | Input directory where Sphinx processes ``rst`` files               | /opt/blog/repo/source                                       | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_DOC_OUTPUT_DIR**                 | Output directory where Sphinx will output the ``html`` files       | /opt/blog/repo/release                                      | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_BASE_DOMAIN**                    | Your web domain like: ``http://jayjohnson.com``                    | http://jaypjohnson.com                                      | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n| **ENV_GOOGLE_ANALYTICS_CODE**          | Your Google Analytics Tracking Code like: ``UA-79840762-99``       | UA-79840762-99                                              | \n+----------------------------------------+--------------------------------------------------------------------+-------------------------------------------------------------+ \n\n.. warning:: Please make sure the **nginx** and **sphinx-bootstrap** containers use the **same base** ``ENV_DEFAULT_ROOT_VOLUME`` directory and that the ``rst`` files are stored inside the ``ENV_DOC_SOURCE_DIR`` and the html output files can be written to the ``ENV_DOC_OUTPUT_DIR`` directory\n\n\nHere is how my EC2 host has the shared directory set up\n\n::\n\n   $ ls /opt/blog/repo/\n   docker-compose.yml  Makefile  nginxssh.sh  README.rst  source  sphinxssh.sh  start_composition.sh  stop_composition.sh\n   $\n\n.. note:: The **release** directory will not be present until you start the composition the first time\n\n\nWant to add a new blog post?\n----------------------------\n\n#. Open a new ``new-post.rst`` file in the ``source`` directory\n\n#. Add the following lines to the new ``new-post.rst`` file:\n\n   ::\n\n       ==================\n       This is a New Post\n       ==================\n   \n       My first blog post\n\n\n#. Edit the ``index.rst`` file and find the ``Site Contents`` section\n\n#. Add a new line to ``Site Contents`` **toctree** section containing: ``new-post`` \n\n   Here is how mine looks after adding it to the ``index.rst``\n\n   ::\n\n       Site Contents\n       -------------\n   \n       .. toctree::\n           :maxdepth: 2\n   \n           new-post\n           python\n           work-history\n           contact\n           about\n\n\n   .. note:: One nice feature of the sphinx framework is it will automatically label the link with the first **Title** inside the file.\n\n#. Save the ``index.rst`` file\n\n#. Deploy and Rebuild the html files\n\n   Inside the ``websphinx`` container I included a `deploy + rebuild script`_ you can run from outside the container with:\n\n   ::\n\n       $ docker exec -it websphinx /root/containerfiles/deploy-new-content.sh\n\n#. Test the new post shows up in the site\n\n   ::\n\n       $ curl -s http://localhost:80/ | grep href | grep toctree | grep \"New Post\"\n       \u003cli class=\"toctree-l1\"\u003e\u003ca class=\"reference internal\" href=\"new-post.html\"\u003eThis is a New Post\u003c/a\u003e\u003c/li\u003e\n       \u003cli class=\"toctree-l1\"\u003e\u003ca class=\"reference internal\" href=\"new-post.html\"\u003eThis is a New Post\u003c/a\u003e\u003c/li\u003e\n       $\n\nStopping the site\n~~~~~~~~~~~~~~~~~\n\nTo stop the site run:\n\n::\n\n    $ ./stop_composition.sh \n    Stopping the Composition\n    Stopping webnginx ... done\n    Stopping websphinx ... done\n    Done\n    $\n\n\n\nCleanup the site containers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf you want to stop and cleanup the site and docker containers run these commands:\n\n#. Check the site containers are running\n\n   ::\n\n       $ docker ps -a\n       CONTAINER ID        IMAGE                               COMMAND                  CREATED             STATUS              PORTS                                      NAMES\n       4159eb49d9d2        jayjohnson/nginx:1.0.0              \"/root/containerfiles\"   20 minutes ago      Up 50 seconds       0.0.0.0:80-\u003e80/tcp, 0.0.0.0:443-\u003e443/tcp   webnginx\n       f0ba0a7d0f4b        jayjohnson/sphinx-bootstrap:1.0.0   \"/root/containerfiles\"   20 minutes ago      Up 50 seconds                                                  websphinx\n       $\n\n#. Stop the composition\n\n   ::\n\n       $ ./stop_composition.sh \n       Stopping the Composition\n       Stopping webnginx ... done\n       Stopping websphinx ... done\n       Done\n       $\n\n#. Remove the containers\n\n   ::\n\n       $ docker rm webnginx websphinx\n       webnginx\n       websphinx\n       $\n\n#. Remove the container images\n\n   ::\n\n       $ docker rmi jayjohnson/nginx:1.0.0 jayjohnson/sphinx-bootstrap:1.0.0\n\n\n#. Remove the blog directory\n\n   :: \n\n       $ rm -rf /opt/blog/repo\n\nLicenses\n--------\n\nThis repository is licensed under the MIT license.\n\nThe nginx license: http://nginx.org/LICENSE\n\nSphinx Bootstrap Theme is licensed under the MIT license.\n\nBootstrap v2 is licensed under the Apache license 2.0.\n\nBootstrap v3.1.0+ is licensed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjay-johnson%2Fdocker-nginx-sphinx-bootstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjay-johnson%2Fdocker-nginx-sphinx-bootstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjay-johnson%2Fdocker-nginx-sphinx-bootstrap/lists"}