{"id":382,"date":"2019-06-03T15:57:23","date_gmt":"2019-06-03T15:57:23","guid":{"rendered":"https:\/\/blog.iabsolute.com\/?p=382"},"modified":"2019-06-03T15:58:16","modified_gmt":"2019-06-03T22:58:16","slug":"how-to-install-the-apache-web-server-on-centos-7","status":"publish","type":"post","link":"https:\/\/blog.iabsolute.com\/?p=382","title":{"rendered":"How To Install the Apache Web Server on CentOS 7"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"step-1-\u2014-installing-apache\">Step 1 \u2014 Installing Apache<\/h2>\n\n\n\n<p>Apache is available within CentOS&#8217;s default software repositories, which means you can install it with the <code>yum<\/code> package manager.<\/p>\n\n\n\n<p>As the non-root sudo user configured in the prerequisites, update the local Apache <code>httpd<\/code> package index to reflect the latest upstream changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo yum update httpd\n<\/code><\/pre>\n\n\n\n<p>Once the packages are updated, install the Apache package:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo yum install httpd\n<\/code><\/pre>\n\n\n\n<p>After confirming the installation, <code>yum<\/code> will install Apache and all required dependencies. Once the installation completes, you are ready to start the service. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-2-\u2014-checking-your-web-server\">Step 2 \u2014 Checking your Web Server<\/h2>\n\n\n\n<p>Apache does not automatically start on CentOS once the installation completes. You will need to start the Apache process manually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl start httpd\n<\/code><\/pre>\n\n\n\n<p>Verify that the service is running with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl status httpd\n<\/code><\/pre>\n\n\n\n<p>You will see an <code>active<\/code> status when the service is running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OutputRedirecting to \/bin\/systemctl status httpd.service\n\u25cf httpd.service - The Apache HTTP Server\n   Loaded: loaded (\/usr\/lib\/systemd\/system\/httpd.service; enabled; vendor preset: disabled)\n   Active: active (running) since Wed 2019-02-20 01:29:08 UTC; 5s ago\n     Docs: man:httpd(8)\n           man:apachectl(8)\n Main PID: 1290 (httpd)\n   Status: \"Processing requests...\"\n   CGroup: \/system.slice\/httpd.service\n           \u251c\u25001290 \/usr\/sbin\/httpd -DFOREGROUND\n           \u251c\u25001291 \/usr\/sbin\/httpd -DFOREGROUND\n           \u251c\u25001292 \/usr\/sbin\/httpd -DFOREGROUND\n           \u251c\u25001293 \/usr\/sbin\/httpd -DFOREGROUND\n           \u251c\u25001294 \/usr\/sbin\/httpd -DFOREGROUND\n           \u2514\u25001295 \/usr\/sbin\/httpd -DFOREGROUND\n...\n<\/code><\/pre>\n\n\n\n<p>As you can see from this output, the service appears to have started successfully. However, the best way to test this is to request a page from Apache.<\/p>\n\n\n\n<p>You can access the default Apache landing page to confirm that the software is running properly through your IP address. If you do not know your server&#8217;s IP address, you can get it a few different ways from the command line.<\/p>\n\n\n\n<p>Type this at your server&#8217;s command prompt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>hostname -I\n<\/code><\/pre>\n\n\n\n<p>This command will display all of the host&#8217;s network addresses, so you will get back a few IP addresses separated by spaces. You can try each in your web browser to see if they work.<\/p>\n\n\n\n<p>Alternatively, you can use <code>curl<\/code> to request your IP from <code>icanhazip.com<\/code>, which will give you your public IPv4 address as seen from another location on the internet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -4 icanhazip.com\n<\/code><\/pre>\n\n\n\n<p>When you have your server&#8217;s IP address, enter it into your browser&#8217;s address bar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:\/\/your_server_ip\n<\/code><\/pre>\n\n\n\n<p>You&#8217;ll see the default CentOS 7 Apache web page:<\/p>\n\n\n\n<p>This page indicates that Apache is working correctly. It also includes some basic information about important Apache files and directory locations. Now that the service is installed and running, you can now use different <code>systemctl<\/code> commands to manage the service.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-3-\u2014-managing-the-apache-process\">Step 3 \u2014 Managing the Apache Process<\/h2>\n\n\n\n<p>Now that you have your web server up and running, let&#8217;s go over some basic management commands.<\/p>\n\n\n\n<p>To stop your web server, type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl stop httpd\n<\/code><\/pre>\n\n\n\n<p>To start the web server when it is stopped, type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl start httpd\n<\/code><\/pre>\n\n\n\n<p>To stop and then start the service again, type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl restart httpd\n<\/code><\/pre>\n\n\n\n<p>If you are simply making configuration changes, Apache can often reload without dropping connections. To do this, use this command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl reload httpd\n<\/code><\/pre>\n\n\n\n<p>By default, Apache is configured to start automatically when the server boots. If this is not what you want, disable this behavior by typing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl disable httpd\n<\/code><\/pre>\n\n\n\n<p>To re-enable the service to start up at boot, type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl enable httpd\n<\/code><\/pre>\n\n\n\n<p>Apache will now start automatically when the server boots again. <\/p>\n\n\n\n<p>The default configuration for Apache will allow your server to host a single website. If you plan on hosting multiple domains on your server, you will need to configure virtual hosts on your Apache web server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-4-\u2014-setting-up-virtual-hosts-recommended\">Step 4 \u2014 Setting Up Virtual Hosts (Recommended)<\/h2>\n\n\n\n<p>When using the Apache web server, you can use <em>virtual hosts<\/em> (similar to server blocks in Nginx) to encapsulate configuration details and host more than one domain from a single server. In this step, you will set up a domain called <code>example.com<\/code>, but you should replace this with your own domain name. To learn more about setting up a domain name with DigitalOcean, see our <a href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/an-introduction-to-digitalocean-dns\">Introduction to DigitalOcean DNS<\/a>.<\/p>\n\n\n\n<p>Apache on CentOS 7 has one server block enabled by default that is configured to serve documents from the <code>\/var\/www\/html<\/code> directory. While this works well for a single site, it can become unwieldy if you are hosting multiple sites. Instead of modifying <code>\/var\/www\/html<\/code>, you will create a directory structure within <code>\/var\/www<\/code> for the <code>example.com<\/code> site, leaving <code>\/var\/www\/html<\/code> in place as the default directory to be served if a client request doesn&#8217;t match any other sites.<\/p>\n\n\n\n<p>Create the <code>html<\/code> directory for <code>example.com<\/code> as follows, using the <code>-p<\/code> flag to create any necessary parent directories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/www\/example.com\/html\n<\/code><\/pre>\n\n\n\n<p>Create an additional directory to store log files for the site:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/www\/example.com\/log\n<\/code><\/pre>\n\n\n\n<p>Next, assign ownership of the <code>html<\/code> directory with the <code>$USER<\/code> environmental variable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chown -R $USER:$USER \/var\/www\/example.com\/html\n<\/code><\/pre>\n\n\n\n<p>Make sure that your web root has the default permissions set:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo chmod -R 755 \/var\/www\n<\/code><\/pre>\n\n\n\n<p>Next, create a sample <code>index.html<\/code> page using <code>vi<\/code> or your favorite editor:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/var\/www\/example.com\/html\/index.html\n<\/code><\/pre>\n\n\n\n<p>Press <code>i<\/code> to switch to <code>INSERT<\/code> mode and add the following sample HTML to the file:\/var\/www\/example.com\/html\/index.html<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;html>\n  &lt;head>\n    &lt;title>Welcome to Example.com!&lt;\/title>\n  &lt;\/head>\n  &lt;body>\n    &lt;h1>Success! The example.com virtual host is working!&lt;\/h1>\n  &lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n\n\n\n<p>Save and close the file by pressing <code>ESC<\/code>, typing <code>:wq<\/code>, and pressing <code>ENTER<\/code>. <\/p>\n\n\n\n<p>With your site directory and sample index file in place, you are almost ready to create the virtual host files. Virtual host files specify the configuration of your separate sites and tell the Apache web server how to respond to various domain requests.<\/p>\n\n\n\n<p>Before you create your virtual hosts, you will need to create a <code>sites-available<\/code> directory to store them in. You will also create the <code>sites-enabled<\/code> directory that tells Apache that a virtual host is ready to serve to visitors. The <code>sites-enabled<\/code> directory will hold symbolic links to virtual hosts that we want to publish. Create both directories with the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir \/etc\/httpd\/sites-available \/etc\/httpd\/sites-enabled\n<\/code><\/pre>\n\n\n\n<p>Next, you will tell Apache to look for virtual hosts in the <code>sites-enabled<\/code> directory. To accomplish this, edit Apache&#8217;s main configuration file and add a line declaring an optional directory for additional configuration files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/httpd\/conf\/httpd.conf\n<\/code><\/pre>\n\n\n\n<p>Add this line to the end of the file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>IncludeOptional sites-enabled\/*.conf\n<\/code><\/pre>\n\n\n\n<p>Save and close the file when you are done adding that line. Now that you have your virtual host directories in place, you will create your virtual host file.<\/p>\n\n\n\n<p>Start by creating a new file in the <code>sites-available<\/code> directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/httpd\/sites-available\/example.com.conf\n<\/code><\/pre>\n\n\n\n<p>Add in the following configuration block, and change the <code>example.com<\/code> domain to your domain name: \/etc\/httpd\/sites-available\/example.com.conf<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;VirtualHost *:80>\n    ServerName www.example.com\n    ServerAlias example.com\n    DocumentRoot \/var\/www\/example.com\/html\n    ErrorLog \/var\/www\/example.com\/log\/error.log\n    CustomLog \/var\/www\/example.com\/log\/requests.log combined\n&lt;\/VirtualHost>\n<\/code><\/pre>\n\n\n\n<p>This will tell Apache where to find the root directly that holds the publicly accessible web documents. It also tells Apache where to store error and request logs for this particular site.<\/p>\n\n\n\n<p>Save and close the file when you are finished.<\/p>\n\n\n\n<p>Now that you have created the virtual host files, you will enable them so that Apache knows to serve them to visitors. To do this, create a symbolic link for each virtual host in the <code>sites-enabled<\/code> directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ln -s \/etc\/httpd\/sites-available\/example.com.conf \/etc\/httpd\/sites-enabled\/example.com.conf\n<\/code><\/pre>\n\n\n\n<p>Your virtual host is now configured and ready to serve content. Before restarting the Apache service, let&#8217;s make sure that SELinux has the correct policies in place for your virtual hosts.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-5-\u2014-adjusting-selinux-permissions-for-virtual-hosts-recommended\">Step 5 \u2014 Adjusting SELinux Permissions for Virtual Hosts (Recommended)<\/h2>\n\n\n\n<p><a href=\"https:\/\/www.digitalocean.com\/community\/tutorial_series\/an-introduction-to-selinux-on-centos-7\">SELinux<\/a> is configured to work with the default Apache configuration. Since you set up a custom log directory in the virtual hosts configuration file, you will receive an error if you attempt to start the Apache service. To resolve this, you need to update the SELinux policies to allow Apache to write to the necessary files. SELinux brings heightened security to your CentOS 7 environment, therefore it is not recommended to completely disable the kernel module. <\/p>\n\n\n\n<p>There are different ways to set policies based on your environment&#8217;s needs, as SELinux allows you to customize your security level. This step will cover two methods of adjusting Apache policies: universally and on a specific directory. Adjusting policies on directories is more secure, and is therefore the recommended approach.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"adjusting-apache-policies-universally\">Adjusting Apache Policies Universally<\/h3>\n\n\n\n<p>Setting the Apache policy universally will tell SELinux to treat all Apache processes identically by using the <code>httpd_unified<\/code> boolean. While this approach is more convenient, it will not give you the same level of control as an approach that focuses on a file or directory policy.<\/p>\n\n\n\n<p>Run the following command to set a universal Apache policy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo setsebool -P httpd_unified 1\n<\/code><\/pre>\n\n\n\n<p>The <code>setsebool<\/code> command changes SELinux boolean values. The <code>-P<\/code> flag will update the boot-time value, making this change persist across reboots. <code>httpd_unified<\/code> is the boolean that will tell SELinux to treat all Apache processes as the same type, so you enabled it with a value of <code>1<\/code>. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"adjusting-apache-policies-on-a-directory\">Adjusting Apache Policies on a Directory<\/h3>\n\n\n\n<p>Individually setting SELinux permissions for the <code>\/var\/www\/example.com\/log<\/code> directory will give you more control over your Apache policies, but may also require more maintenance. Since this option is not universally setting policies, you will need to manually set the context type for any new log directories specified in your virtual host configurations.<\/p>\n\n\n\n<p>First, check the context type that SELinux gave the <code>\/var\/www\/example.com\/log<\/code> directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ls -dZ \/var\/www\/example.com\/log\/\n<\/code><\/pre>\n\n\n\n<p>This command lists and prints the SELinux context of the directory. You will see output similar to the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outputdrwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 \/var\/www\/example.com\/log\/\n<\/code><\/pre>\n\n\n\n<p>The current context is <code>httpd_sys_content_t<\/code>, which tells SELinux that the Apache process can only read files created in this directory. In this tutorial, you will change the context type of the <code>\/var\/www\/example.com\/log<\/code> directory to <code>httpd_log_t<\/code>. This type will allow Apache to generate and append to web application log files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo semanage fcontext -a -t httpd_log_t \"\/var\/www\/example.com\/log(\/.*)?\"\n<\/code><\/pre>\n\n\n\n<p>Next, use the <code>restorecon<\/code> command to apply these changes and have them persist across reboots:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo restorecon -R -v \/var\/www\/example.com\/log\n<\/code><\/pre>\n\n\n\n<p>The <code>-R<\/code> flag runs this command recursively, meaning it will update any existing files to use the new context. The <code>-v<\/code> flag will print the context changes the command made. You will see the following output confirming the changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outputrestorecon reset \/var\/www\/example.com\/log context unconfined_u:object_r:httpd_sys_content_t:s0->unconfined_u:object_r:httpd_log_t:s0\n<\/code><\/pre>\n\n\n\n<p>You can list the contexts once more to see the changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ls -dZ \/var\/www\/example.com\/log\/\n<\/code><\/pre>\n\n\n\n<p>The output reflects the updated context type:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Outputdrwxr-xr-x. root root unconfined_u:object_r:httpd_log_t:s0 \/var\/www\/example.com\/log\n<\/code><\/pre>\n\n\n\n<p>Now that the <code>\/var\/www\/example.com\/log<\/code> directory is using the <code>httpd_log_t<\/code> type, you are ready to test your virtual host configuration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-6-\u2014-testing-the-virtual-host-recommended\">Step 6 \u2014 Testing the Virtual Host (Recommended)<\/h2>\n\n\n\n<p>Once the SELinux context has been updated with either method, Apache will be able to write to the <code>\/var\/www\/example.com\/log<\/code> directory. You can now successfully restart the Apache service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl restart httpd\n<\/code><\/pre>\n\n\n\n<p>List the contents of the <code>\/var\/www\/example.com\/log<\/code> directory to see if Apache created the log files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ls -lZ \/var\/www\/example.com\/log\n<\/code><\/pre>\n\n\n\n<p>You&#8217;ll see that Apache was able to create the <code>error.log<\/code> and <code>requests.log<\/code> files specified in the virtual host configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Output-rw-r--r--. 1 root root 0 Feb 26 22:54 error.log\n-rw-r--r--. 1 root root 0 Feb 26 22:54 requests.log\n<\/code><\/pre>\n\n\n\n<p>Now that you have your virtual host set up and SELinux permissions updated, Apache will now serve your domain name. You can test this by navigating to <code>http:\/\/example.com<\/code>, where you should see something like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/CART-65406\/virtual_host_success.png\" alt=\"Success! The example.com virtual host is working!\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Step 1 \u2014 Installing Apache Apache is available within CentOS&#8217;s default software repositories, which means you can install it with the yum package manager. As the non-root sudo user configured in the prerequisites, update the local Apache httpd package index &hellip; <a href=\"https:\/\/blog.iabsolute.com\/?p=382\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25,10],"tags":[],"class_list":["post-382","post","type-post","status-publish","format-standard","hentry","category-apache","category-centos"],"_links":{"self":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/382","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=382"}],"version-history":[{"count":2,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/382\/revisions"}],"predecessor-version":[{"id":384,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=\/wp\/v2\/posts\/382\/revisions\/384"}],"wp:attachment":[{"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.iabsolute.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}