Tag: web

  • Installing WordPress on a self-managed server using docker, and getting https to work with it, too

    This project had a couple of objectives to it:

    1. “practice” modern website and cybersecurity practices
    2. make a website

    I guess I expected there would be a concisely documented solution to this but if there is, it was not coming up for me in searches. Nearly every site I referenced made it sound like it was going to lead me where I wanted to go and would ultimately end in doing this through cPanel. cPanel is not required for a wordpress site to work, so I didn’t want to conflate the two.


    1. “practice” modern website and cybersecurity practices

    Attack vectors include the web service as well as the web server.

    Webserver hardening typically involves firewalls, and not allowing privileged/root users to be log-in directly via ssh. In short, making it hard to access the server, and making it even harder to do anything undesirable to it even if you can.

    Isolate of an application (web service) from the operating system running the computer will be done using docker.

    Within docker, there are all sorts of “good practices” and “bad practices”. Let’s try to use some good ones here by working with containerized microprocesses

    • isolate web-accessible webpage and web server from the underlying computer running it all.
    • improved maintainability
      • infrastucture as code (IAC) – not talking about terraform or ansible here–just docker-compose

    I don’t want the server OS and filesystem being an integral and inseparable part of this application. If someone knows now to break wordpress remotely, they could theoretically get access to the file system of the server, poke around, change things, take over.

    Microservices is a concept where you divide a project into its individual components which are all isolated from each other except through the interfaces they use to talk to each other. They are tiny and have only the bare minimum for their individual services to work. Breaking/updating one does not affect the other or endanger data loss in the other.

    I’ve worked with docker plenty and feel very comfortable with it, but my experience with docker is generally to make and use build environments–not applications. I could make individual docker containers for the services, and orchestrate the manually, or i could use **docker-compose**. Though I’ve known about docker-compose for a few years and have started a few demonstrative projects using docker-compose, I wanted to use it with a greater purpose. I figured this would be a great opportunity to do that.

    2. make a website

    There’s a lot to put here. As I see things right now, there are a couple of ways to make a website: code it yourself or use a website builder.

    • code it yourself (harder)
      • need to learn:
        • html
        • css
        • javascript
        • php
        • SQL (if more than a simple landing page or anything with static content.
      • need to optionally learn other more advanced tools, depending on what you want your website to do:
        • django?
        • flask
        • node.js
        • more…
    • use a website builder(easier) (listed in no particular order)
      • wordpress
      • wix
      • squarespace

    I have elementary html and javascript knowledge at this point and could make some static content, but it would take me a while to make something as usable as wordpress with all of its databasing, widgets, classes, etc.. So I went with wordpress. which is also open-source and free.

    wordpress is pretty much a collection of php scripts that contain within themselves credentials to interface with a SQL service on the same server to manage the underlying database of users, posts, etc.

    Making a website requires a few things:

    1. code that makes up the web pages
      • wordpress is going to manage this all for me
    2. a program that sends that code to others on the internet when asked (web service)
      • nginx and apache are common choices here, and I’m not looking to complicate things for myself any more than necessary right now by choosing something more obscure.
    3. a computer/OS to run the program in (2.) above
      • if I was paying a company to host my site on a shared computer, I’d get a lot for “free” with that solution, but there would be less to learn
      • I’m opting to host it myself on a dedicated server. If you have the know-how, you could find out where.

    Let’s get into docker-compose:

    There’s a lot documented on this process, already, so I’m not going to reiterate what I don’t think is necessary to reiterate. As a starting point, I referenced https://github.com/docker/awesome-compose/blob/master/official-documentation-samples/wordpress/README.md from which I grabbed their sample compose.yml:

    services:
      db:
        # We use a mariadb image which supports both amd64 & arm64 architecture
        image: mariadb:10.6.4-focal
        # If you really want to use MySQL, uncomment the following line
        #image: mysql:8.0.27
        command: '--default-authentication-plugin=mysql_native_password'
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          - MYSQL_ROOT_PASSWORD=somewordpress
          - MYSQL_DATABASE=wordpress
          - MYSQL_USER=wordpress
          - MYSQL_PASSWORD=wordpress
        expose:
          - 3306
          - 33060
      wordpress:
        image: wordpress:latest
        volumes:
          - wp_data:/var/www/html
        ports:
          - 80:80
        restart: always
        environment:
          - WORDPRESS_DB_HOST=db
          - WORDPRESS_DB_USER=wordpress
          - WORDPRESS_DB_PASSWORD=wordpress
          - WORDPRESS_DB_NAME=wordpress
    volumes:
      db_data:
      wp_data:

    Personally, I hate using docker volumes, so I edited a few key parts

    • passwords
    • volumes

    The wordpress image is forwarding its port 80 to the host’s port 80. This is the port of http traffic, meaning that the wordpress image comes with a web service inbuilt. A quick ls /etc showed apache2 and not nginx.

    prerequisites:

    1. ssl certificates and key
    2. familiarity with Linux
    3. familiarity with docker

    Get https working:

    1. update compose.yml to give the image access to the ssl certs and to give myself access to the wordpress configs
     wordpress:
        image: wordpress:latest
        volumes:
          - ./wp_data:/var/www/html
          - /path/to/ssl/certs/on/host:/etc/ssl/certs:ro
          - /path/to/private/key/on/host:/etc/ssl/private:ro
          - /path/to/sites-available/on/host:/etc/apache2/sites-available:ro
          - /path/to/sites-enabled/on/host:/etc/apache2/sites-enabled:ro
        ports:
          - 80:80
          - 443:443

    2. update /etc/apache2/sites-available/default-ssl.conf

            #   SSL Engine Switch:
            #   Enable/Disable SSL for this virtual host.
            SSLEngine on
    
            #   A self-signed (snakeoil) certificate can be created by installing
            #   the ssl-cert package. See
            #   /usr/share/doc/apache2/README.Debian.gz for more info.
            #   If both key and certificate are stored in the same file, only the
            #   SSLCertificateFile directive is needed.
            SSLCertificateFile      /etc/ssl/certs/certificate.crt
            SSLCertificateKeyFile   /etc/ssl/private/server.key
            SSLCertificateChainFile /etc/ssl/certs/ca-bundle.crt

    The needed changes/additions are highlighted.

    3. enable the ssl

    #start the container first if it's not already up
    docker-compose up -d
    
    #now run a command to enable the ssl module in apache2
    docker exec wordpress_container_name a2enmod ssl

    4. enable the default-ssl.conf file

    cd sites-enabled
    ln -s ../sites-available/default-ssl.conf default-ssl.conf

    5. restart the apache server

    docker-compose restart

    6. profit.

    https://johnhosford.com. enjoy the https.

    next steps:

    1. add cPanel and maybe phpmyadmin to the compose.yml so I have more of the full-featured offering that many hosting services offer.