概要

本記事では図のように、ホスト上のNginxがリバースプロキシとして稼働し、以下のアクセスを各アプリに振り分けるようなWebサーバーを構築する手順を解説します。
- https://example.com
- https://www.example.com
- https://gitlab.example.com
- https://redmine.example.com
- https://node.example.com
動作確認環境:Ubuntu20.04
ざっくりした手順
手順は、サーバ準備とサーバ構築に分類してみましたが、本記事ではサーバ構築をメインに解説します。
- VPSを準備する(さくらのVPS
、ConoHa VPS あたりがおすすめ) - ドメインを準備する(お名前.com
がおすすめ) - DNS設定をする
- Nginxをインストール・設定する
- SSL化する
- Docker・Docker-Composeをインストールする
- 各アプリのコンテナを起動する
- WordPress
- GitLab
- Redmine
- Node.jsアプリ
サーバ準備
ここでは、サーバを準備する手順をざっくり紹介しています。DNS設定は手続きが完了してから、設定が反映されるまで時間(数時間〜72時間)がかかることがあるので、早めに済ませておくことをおすすめします。
VPSを準備する
さくらのVPSにアクセスして、2週間のお試し登録をする。
ドメインを取得する
お名前.comにアクセスして、何でもいいので、ドメインを取得する。1円のものでOK.
DNSを設定する
1.VPSのグローバルIPアドレスをメモする。
(さくらのVPSなら、コンソールから確認できる)
2.以下のようにDNS設定を行う。
(お名前.com Navi>ドメイン設定>DNS設定 から設定する)
ホスト名 | TYPE | VALUE |
---|---|---|
example.com | A | 1.でメモしたIPアドレス |
www.example.com | CNAME | example.com |
gitlab.example.com | CNAME | example.com |
redmine.example.com | CNAME | example.com |
node.example.com | CNAME | example.com |
3.「example.com」の名前解決ができるか確認しておく。
サーバ構築
ここからは、実際に設定ファイルを作成したり、コマンドを叩いたりして、サーバを構築していきます。
Nginxをインストール・設定する
まずは、Nginxをインストールする
# apt-get準備
sudo apt-get install update
sudo apt-get install upgrade -y
# nginxをインストール
sudo apt-get install nginx
つぎに、Nginxの設定ファイルを編集して、各サブドメインでのアクセスを後で起動するコンテナに流すように設定する。
/etc/nginx/sites-availble/default
を以下のように修正
# Default(WordPress) server configuration
#
server {
listen 80;
server_name www.nattoserver.net nattoserver.net;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://localhost:18080;
}
}
# GitLab server configuration
#
server {
listen 80;
server_name gitlab.nattoserver.net;
location / {
proxy_set_header Host $http_host;
proxy_pass http://localhost:31080;
}
}
# Redmine server configuration
#
server {
listen 80;
server_name redmine.nattoserver.net;
location / {
proxy_set_header Host $http_host;
proxy_pass http://localhost:3000;
}
}
# nodeapp server configuration
#
server {
listen 80;
server_name node.nattoserver.net;
location / {
proxy_set_header Host $http_host;
proxy_pass http://localhost:38080;
}
}
SSL化する
各サーバ(FQDN)すべてをSSL化してしまいます。
# certbotをインストール
sudo apt-get install certbot python3-certbot-nginx
# SSL化する
sudo certbot --nginx -d nattoserver.net \
-d www.nattoserver.net \
-d gitlab.nattoserver.net \
-d redmine.nattoserver.net \
-d node.nattoserver.net
Docker・Docker-Composeをインストールする
公式サイト(Ubuntuの場合):https://docs.docker.com/engine/install/ubuntu/
# docker(スクリプトでインストール)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo rm get-docker.sh
# docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# バージョンは適宜変更
# docker-composeコマンドの実行権限を変更する
sudo chmod +x /usr/local/bin/docker-compose
各アプリのコンテナを起動する
基本的には、各アプリに対して以下のことをやるだけです。
- 作業フォルダを作成
- docker-compose.ymlを作成
- コンテナ起動
環境変数を使用したり、しなかったり、ポート番号などは、ご使用の環境に合わせて変更してみてください。
※ポート番号を変更した場合は、忘れずにNginxの設定ファイルも変更してください。
WordPress

作業ディレクトリを作成して、環境変数を作成
# 作業ディレクトリを作成して、以後ここで作業
sudo mkdir /srv/wordpress
cd /srv/wordpress
# docker-compose.yml内で使用する環境変数を.envファイルに記載しておく
sudo touch .env
MYSQL_ROOT_PASSWORD=AAA
DB_NAME=XXX
DB_USER=YYY
DB_PASSWORD=ZZZ
docker-compose.ymlを作成して、中身を編集
# docker-compose.ymlを作成して、以下のようにする
sudo touch docker-compose.yml
version: "3"
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $DB_NAME
MYSQL_USER: $DB_USER
MYSQL_PASSWORD: $DB_PASSWORD
ports:
- '13306:3306'
volumes:
- db_data:/var/lib/mysql
command: --port 13306 # 3306, 33060 以外の場合は必要(https://qiita.com/ryuji-oda/items/c3ed1b86fe0c1f2b9058)
wordpress:
container_name: wordpress
image: wordpress:php8.0-fpm
restart: always
depends_on:
- db
expose:
- '9000'
environment:
WORDPRESS_DB_HOST: db:13306
WORDPRESS_DB_NAME: $DB_NAME
WORDPRESS_DB_USER: $DB_USER
WORDPRESS_DB_PASSWORD: $DB_PASSWORD
WORDPRESS_CONFIG_EXTRA: "define('WP_HOME','https://example.com'); define('WP_SITEURL','https://example.com');"
volumes:
- ./wordpress_data:/var/www/html
links:
- db
wp-nginx:
image: nginx:1.21
restart: always
depends_on:
- wordpress
ports:
- '18080:80'
volumes:
- ./nginx:/etc/nginx/conf.d
- ./logs/nginx:/var/log/nginx
- ./wordpress_data:/var/www/html
3306, 33060 以外の場合は必要`command: –port 13306`のようにしてあげないと、接続できなかった。
参考:https://qiita.com/ryuji-oda/items/c3ed1b86fe0c1f2b9058
※今のところ公式サイトで該当箇所が見つからない
コンテナ内で使用するNginx設定ファイルを作成する
# コンテナ内で使用するnginx設定ファイルを作成
sudo mkdir /etc/wordpress/nginx # マウントするディレクトリ内に配置する
sudo touch default.conf
server {
listen 80;
server_name _;
root /var/www/html;
index index.php index.html index.htm;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
#client_max_body_size 128M;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000; # ワードプレス自体のコンテナ名:ポート番号
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
コンテナを起動する
# 起動
docker-compose up -d
コンテナが起動したら、「https://example.com」もしくは「https://www.example.com」にアクセスすれば、ワードプレスの初期画面が表示されるはずです。
※mb4対応はまた別途(ToDo)
GitLab

作業ディレクトリを作成する。
# 作業ディレクトリを作成して、以後ここで作業
sudo mkdir /srv/gitlab
cd /srv/gitlab
docker-compose.ymlを作成して、中身を編集
# docker-compose.ymlを作成して、以下のようにする
sudo touch docker-compose.yml
version: "3"
services:
gitlab:
image: 'gitlab/gitlab-ce:latest' # ee版を使ってもいい
restart: always
hostname: 'gitlab.nattoserver.net'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.nattoserver.net'
nginx['listen_port'] = 80
nginx['listen_https'] = false
letsencrypt['enable'] = false
ports:
- '31080:80'
volumes:
- './gitlab/config:/etc/gitlab'
- './gitlab/logs:/var/log/gitlab'
- './gitlab/data:/var/opt/gitlab'
gitlab-runner:
image: 'gitlab/gitlab-runner:latest'
restart: always
volumes:
- './gitlab-runner/config:/etc/gitlab-runner'
- '/var/run/docker.sock:/var/run/docker.sock'
このままdockerを起動すると、エラーが出るので、config.tml
ファイルを作成しておく。
# こんなエラーが出る
gitlab-runner_1 | ERROR: Failed to load config stat /etc/gitlab-runner/config.toml: no such file or directory builds=0
# config.tomlファイルを作っておく
sudo mkdir /etc/gitlab-runner
sudo touch /etc/gitlab-runner/config.toml
コンテナを起動する
# 起動
docker-compose up -d
この状態で、「https://gitlab.example.com」にアクセスすると、ログイン画面が表示されるが、rootのパスワードも分からない状態である。
そのため、コンテナに接続して、直接rootのパスワードを編集する。
# コンテナに接続する
sudo docker exec -it [コンテナ名] bash
# コンテナ名は`sudo docker ps`したときのNAMESでわかる
Railsコンソールを起動する
# Railsコンソールを起動して接続
gitlab-rails console -e production # 時間がかかるので待つ
rootのパスワードを変更する
# rootを取得
user = User.find(1)
# パスワードを設定
user.password = 'Xxx'
user.password_confirmation = 'Xxx'
# 保存
user.save!
# Railsコンソール終了
exit
再度「https://gitlab.example.com」に接続して、設定したパスワードでログインできるはず。
- GitLab Runnerを登録する(https://docs.gitlab.com/runner/register/index.html#docker)
# 対話型の登録フローを開始
sudo docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
# Enter the GitLab instance URL (for example, https://gitlab.com/):
[GitLabのトップページ]
# Enter the registration token:
[CI/CDページで取得したトークン]
# Enter a description for the runner:
[分かりやすい名前] 後で変更可能
# Enter tags for the runner (comma-separated):
[ランナーに付与したいタグ]]
ちなみに、何も入力せずエンターで良い。後で変更可能
# Enter an executor: custom, docker, docker-ssh, shell, ssh, kubernetes, parallels, virtualbox, docker+machine, docker-ssh+machine:
docker
# Enter the default Docker image (for example, ruby:2.6):
ruby:2.6
プロジェクト>設定>CI/CD>一般のパイプライン の `CI/CD configuration file`にciファイルの名前を設定しておく。
- メールが飛ぶようにする(Gmail編:https://docs.gitlab.com/omnibus/settings/smtp.html#gmail)
※前提として、「Gmailの2段階認証プロセスを有効にする」「アプリパスワードを設定する」は済ませておくこと。
docker-compose.ymlファイルにSMTPサーバの情報を記載して、コンテナを再起動すれば完了する。
version: '3'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
restart: always
hostname: 'gitlab.nattoserver.net'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.nattoserver.net'
nginx['listen_port'] = 80
nginx['listen_https'] = false
letsencrypt['enable'] = false
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "<your_user_name>@gmail.com"
gitlab_rails['smtp_password'] = "<アプリパスワード16桁>"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
ports:
- '31080:80'
volumes:
- './gitlab/config:/etc/gitlab'
- './gitlab/logs:/var/log/gitlab'
- './gitlab/data:/var/opt/gitlab'
gitlab-runner:
image: 'gitlab/gitlab-runner:latest'
restart: always
volumes:
- './gitlab-runner/config:/etc/gitlab-runner'
- '/var/run/docker.sock:/var/run/docker.sock'
Redmine

作用ディレクトリを作成する
# 作業ディレクトリを作成して、以後ここで作業
sudo mkdir /srv/gitlab
cd /srv/gitlab
docker-compose.ymlを作成して、中身を編集する
# docker-compose.ymlを作成して、以下のようにする
sudo touch docker-compose.yml
version: '3'
services:
redmine:
image: redmine:4.2.2
restart: always
ports:
- 3000:3000
volumes:
- ./data/plugins:/usr/src/redmine/plugins
- ./data/themes:/usr/src/redmine/public/themes
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: password
REDMINE_SECRET_KEY_BASE: supersecretkey
REDMINE_DB_ENCODING: utf8mb4 # DBの文字コードを設定(Unicode対応)
depends_on:
- db
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: redmine
ports:
- 3306:3306
volumes:
- ./mysql:/var/lib/mysql
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci # Unicode対応
Unicode対応しておかないと、日本語のプロジェクトを作成しようとしたりすると、内部エラーが発生する。
※もし、日本語対応せずにコンテナ起動してしまった場合は、バインドマウントしたホストPC側のディレクトリ削除(上記の`./data`に相当)と、コンテナ削除をしてから、再度コンテナを立ち上げること。
コンテナを起動する
# 起動
docker-compose up -d
「https://redmine.example.com」にアクセスして、初期設定を済ませる。
Node.jsアプリ

Node.jsアプリだけ、Dockerfileを作成して、オリジナルのアプリを動かすDockerイメージを作成してみた。
作業ディレクトリを作成する
sudo mkdir ~/workDockerfile
sudo mkdir ~/workDockerfile/nodeapp
cd ~/workDockerfile/nodeapp
サンプリのnodeアプリを作っていく
# 必要なものをインストール
sudo apt-get install node npm
# nodeアプリを作成
sudo npm init -y # package.jsonが作成される
作成されるpackage.jsonに以下のように修正を加え、npm install
したときにexpress
をインストールするようにする。
"name": "nodeapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC", //★「,」追加
"dependencies": { //★追加
"express": "^4.16.1"
}
}
アプリのメインのソースファイルを作成する
sudo touch index.js
const express = require('express');
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
// App
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
Dockerfileを作成して、中身を編集する
sudo touch Dockerfile
# ベースイメージをpullしてくる
# https://hub.docker.com/_/node?tab=description&page=1&ordering=last_updated
FROM node:10
# アプリディレクトリを作成し。以降ここで作業する
#(コンテナ側のディレクトリを示している)
WORKDIR /usr/src/app
# アプリの依存関係定義ファイルをインストールする
# ワイルドカードを使用して、package.json と package-lock.json の両方が確実にコピーされるようにする
# ホストPC コンテナ側 の順で記述する
COPY package*.json ./
# パッケージをインストールする
RUN npm install
# アプリケーションのソースをバンドルする
# (今でいうと、index.jsをコピーしている)
COPY . .
# コンテナの8080ポートにマッピングするようdockerに通知する
EXPOSE 8080
# nodeアプリを実行する
CMD [ "node", "index.js" ]
Dockerビルド時に、無駄なファイルを含めないようにする
sudo touch .dockerignore
node_modules
npm-debug.log
現時点で、ディレクトリはこんな感じ
~/workDockerfile/nodeapp
├── Dockerfile
├── index.js
└── package.json
Dockerイメージをビルドして、コンテナ起動までしてしまう
# ビルドする
docker build . -t hondakenya/node-sample:1.0
# ビルドされたイメージを確認する
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# hondakenya/node-sample 1.0 34efb0bb8631 4 minutes ago 914MB
# node 10 28dca6642db8 4 months ago 910MB
# コンテナを起動する
docker run -p 38080:8080 -d hondakenya/node-sample:1.0
# アクセスして動作確認
curl localhost:38080
# Hello World
ちなみに、docker-compose.yml
だとこうなる。
version: "3"
services:
node:
image: hondakenya/node-sample:1.0
restart: always
ports:
- 38080:8080
前提:Docker Hubアカウントを作成しておく
# Docker Hubにログインする
docker login
# イメージにタグを付ける
# 命名規則 → <Docker ID>/<イメージ名>:<タグ名>
docker image tag node-sample hondakenya/node-sample:1.0
# イメージを確認する
docker images
# REPOSITORY TAG IMAGE ID CREATED SIZE
# hondakenya/node-sample 1.0 34efb0bb8631 About an hour ago 914MB
# node 10 28dca6642db8 4 months ago 910MB
# プッシュする
docker push hondakenya/node-sample:1.0
やり残していること
- 軽量なDockerイメージを選択すること
- 各コンテナのログファイルをホスト側にバインドマウントすること
- ワードプレスのutfmb4対応
- これらをGit管理すること
コメント