{"id":312,"date":"2022-12-21T16:30:48","date_gmt":"2022-12-21T15:30:48","guid":{"rendered":"https:\/\/munnik.net\/?p=312"},"modified":"2022-12-23T16:58:40","modified_gmt":"2022-12-23T15:58:40","slug":"how-this-site-is-hosted","status":"publish","type":"post","link":"https:\/\/munnik.net\/?p=312","title":{"rendered":"How this site is hosted"},"content":{"rendered":"\n<p>This&nbsp;<strong>WordPress<\/strong> site is hosted on a cloud-vm at&nbsp;<strong>Hetzner<\/strong>. The cloud-vm is configured as a docker host. Multiple websites are hosted, each running in their own&nbsp;<strong>docker<\/strong>&nbsp;container (some running an additional&nbsp;<strong>MySQL<\/strong>&nbsp;database server in a separate container). An&nbsp;<strong>Nginx reverse-proxy<\/strong>&nbsp;runs in its own container, taking care of the routing of the different domains to their respective websites.&nbsp;<strong>Certbot<\/strong>, also running in a separate container, takes care of the https-certificates (using&nbsp;<strong>Let\u2019s Encrypt<\/strong>).<\/p>\n\n\n\n<p>The whole setup is supprisingly simple, just using 2 configuration files. And apart from the docker-host itself, no additional software needs to be preinstalled.&nbsp;<\/p>\n\n\n\n<p>A&nbsp;<code>'docker-compose up'<\/code>&nbsp;pulls in the docker images and fires up all the containers!<\/p>\n\n\n\n<p>The&nbsp;<code>docker-compose.yml<\/code>&nbsp;file looks as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>version: '3.1'\n\nservices:\n  proxy:\n    image: nginx\n    ports:\n      - 80:80\n      - 443:443\n    volumes:\n      - .\/proxy\/nginx.conf:\/etc\/nginx\/nginx.conf:ro\n      - .\/proxy\/certs:\/certs:ro\n      - .\/certbot\/www:\/var\/www\/certbot:ro\n      - .\/certbot\/conf:\/etc\/nginx\/ssl:ro\n\n  certbot:\n    image: certbot\/certbot:latest\n    volumes:\n      - .\/certbot\/www:\/var\/www\/certbot:rw\n      - .\/certbot\/conf:\/etc\/letsencrypt:rw\n\n  site1:\n    image: nginx\n    volumes:\n      - .\/site1\/html:\/usr\/share\/nginx\/html\n    restart: always\n\n  site2:\n    image: wordpress\n    restart: always\n    environment:\n      WORDPRESS_DB_HOST: db2\n      WORDPRESS_DB_USER: some-user\n      WORDPRESS_DB_PASSWORD: some-password\n      WORDPRESS_DB_NAME: some-name\n    volumes:\n      - .\/site2\/html:\/var\/www\/html\n\n  db2:\n    image: mysql:5.7\n    restart: always\n    environment:\n      MYSQL_DATABASE: some-name\n      MYSQL_USER: some-user\n      MYSQL_PASSWORD: some-password\n      MYSQL_RANDOM_ROOT_PASSWORD: '1'\n    volumes:\n      - .\/db2\/db:\/var\/lib\/mysql\n\n  site3:\n    image: wordpress\n    restart: always\n    environment:\n      WORDPRESS_DB_HOST: db3\n      WORDPRESS_DB_USER: some-user\n      WORDPRESS_DB_PASSWORD: some-password\n      WORDPRESS_DB_NAME: some-name\n    volumes:\n      - .\/site3\/html:\/var\/www\/html\n\n  db3:\n    image: mysql:5.7\n    restart: always\n    environment:\n      MYSQL_DATABASE: some-name\n      MYSQL_USER: some-user\n      MYSQL_PASSWORD: some-password\n      MYSQL_RANDOM_ROOT_PASSWORD: '1'\n    volumes:\n      - .\/db3\/db:\/var\/lib\/mysql<\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>nginx.conf<\/code>&nbsp;file (for the reverse-proxy) looks as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user nginx;\nworker_processes 1;\n\nevents {\n  worker_connections 1024;\n}\n\nhttp {\n  include mime.types;\n  default_type application\/octet-stream;\n\n  keepalive_timeout 65;\n\n  #ssl_certificate           \/certs\/cert.crt;\n  #ssl_certificate_key       \/certs\/cert.key;\n\n  ssl_session_cache  builtin:1000  shared:SSL:10m;\n  ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;\n  ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;\n  ssl_prefer_server_ciphers on;\n\n  proxy_set_header Host $host;\n  proxy_set_header X-Forwarded-Proto https;\n  proxy_set_header X-Real-IP $remote_addr;\n  proxy_set_header X-Forwarded-Host $host;\n  proxy_set_header X-Forwarded-Port $server_port;\n\n  client_max_body_size 10M;\n\n  server {\n    listen 80;\n    server_name munnik.xyz wildhunt.nl munnik.net www.munnik.net;\n\n    location \/.well-known\/acme-challenge\/ {\n      root \/var\/www\/certbot;\n    }\n\n    location \/ {\n      return 301 https:\/\/$host$request_uri;\n    }\n  }\n\n  server {\n    listen 443 ssl;\n    server_name wildhunt.nl;\n\n    ssl_certificate \/etc\/nginx\/ssl\/live\/wildhunt.nl\/fullchain.pem;\n    ssl_certificate_key \/etc\/nginx\/ssl\/live\/wildhunt.nl\/privkey.pem;\n\n    location \/ {\n      proxy_pass http:\/\/site1;\n    }\n  }\n\n  server {\n    listen 443 ssl;\n    server_name munnik.xyz;\n\n    ssl_certificate \/etc\/nginx\/ssl\/live\/munnik.xyz\/fullchain.pem;\n    ssl_certificate_key \/etc\/nginx\/ssl\/live\/munnik.xyz\/privkey.pem;\n\n    location \/ {\n      proxy_pass http:\/\/site2;\n    }\n  }\n\n  server {\n    listen 443 ssl;\n    server_name munnik.net www.munnik.net;\n\n    ssl_certificate \/etc\/nginx\/ssl\/live\/munnik.net\/fullchain.pem;\n    ssl_certificate_key \/etc\/nginx\/ssl\/live\/munnik.net\/privkey.pem;\n\n    location \/ {\n      proxy_pass http:\/\/site3;\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>To facilitate uploading of files larger than 2 MB, a small tweak is required in the&nbsp;<code>docker-compose.yml<\/code>&nbsp;file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  site2:\n    image: wordpress\n    restart: always\n    environment:\n      WORDPRESS_DB_HOST: db2\n      WORDPRESS_DB_USER: some-user\n      WORDPRESS_DB_PASSWORD: some-password\n      WORDPRESS_DB_NAME: some-name\n    volumes:\n      - .\/site2\/html:\/var\/www\/html\n      <strong>- .\/site2\/uploads.ini:\/usr\/local\/etc\/php\/conf.d\/uploads.ini:ro<\/strong><\/code><\/pre>\n\n\n\n<p>This overrides the&nbsp;<strong>php<\/strong>&nbsp;settings in the container with the values in the&nbsp;<code>upload.ini<\/code>&nbsp;file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>file_uploads = On\nmemory_limit = 500M\nupload_max_filesize = 500M\npost_max_size = 500M\nmax_execution_time = 600<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This&nbsp;WordPress site is hosted on a cloud-vm at&nbsp;Hetzner. The cloud-vm is configured as a docker host. Multiple websites are hosted, each running in their own&nbsp;docker&nbsp;container [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":320,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[57,58,54,56,55],"class_list":["post-312","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-certbot","tag-docker","tag-mysql","tag-nginx","tag-wordpress","col-md-4 col-sm-4"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/munnik.net\/wp-content\/uploads\/docker-whale-home-logo.png?fit=960%2C546&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p1YJQj-52","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/posts\/312","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/munnik.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=312"}],"version-history":[{"count":2,"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/posts\/312\/revisions"}],"predecessor-version":[{"id":321,"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/posts\/312\/revisions\/321"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/munnik.net\/index.php?rest_route=\/wp\/v2\/media\/320"}],"wp:attachment":[{"href":"https:\/\/munnik.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=312"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/munnik.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=312"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/munnik.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=312"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}