CircleCI? ?? ?? Docker ??? Les gens devraient regarder cela en premier. ↑
Étudier pour étudier ne veut pas dire grand-chose ... Alors bougez d'abord vos mains! Alors cette fois, j'écrirai un article dans un format pratique. J'espère que ceux qui le liront pourront rapidement créer un environnement de développement et se concentrer rapidement sur le développement.
Je l'ai reproduit dans mon environnement environ 3 fois afin de ne pas souffrir au maximum d'erreurs.
Je pense que ce sera probablement une trilogie ... Je suis désolé, c'est long.
Premièrement: cet article 2e: [[Part 2] Déployez automatiquement le service WEB créé avec Rails + Nuxt + MySQL + Docker avec ECS / ECR / CircleCI et faites-le terraform](https://qiita.com/Shogo1222/items/ dcbc1e50f6fc83f48b44) Troisièmement: [Partie 2] Déployez automatiquement le service WEB créé avec Rails + Nuxt + MySQL + Docker avec ECS / ECR / CircleCI et faites-le terraformer
C'est long, mais faisons de notre mieux!
MacOS Catalina 10.15.5 Rails 6.0.3.2 @vue/cli 4.4.4 @nuxt/cli v2.14.4 Vuetify Docker(forMac) version 19.03.8 docker-compose version 1.25.5
--Docker installé
Installer Docker sur Mac (mise à jour: 2019/7/13)
--CircleCI compte créé
Je viens de démarrer CircleCI, donc je l'ai résumé d'une manière facile à comprendre
--Création d'un compte git
[6.1 Préparation et configuration du compte GitHub](https://git-scm.com/book/ja/v2/GitHub-%E3%82%A2%E3%82%AB%E3%82%A6%E3% 83% B3% E3% 83% 88% E3% 81% AE% E6% BA% 96% E5% 82% 99% E3% 81% A8% E8% A8% AD% E5% AE% 9A)
J'ai donné le produit fini à git. qiita-sample-app
app //N'importe quel nom va bien
├─docker-compose.yml
├─front
| ├─Dockerfile
└─back
├─Dockerfile
├─Gemfile
└─Gemfile.lock
mkdir app
cd app //Aller à l'App
mkdir front //création avant
mkdir back //création de retour
touch ./back/Dockerfile
touch ./back/Gemfile
touch ./back/Gemfile.lock
mkdir ./back/environments
touch ./back/environments/db.env
touch ./front/Dockerfile
touch docker-compose.yml
Modifier Dockerfile dans / arrière
back/Dockerfile
#Spécifier une image
FROM ruby:2.6.3-alpine3.10
#Télécharger les packages requis
ENV RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata mysql-dev mysql-client yarn" \
DEV_PACKAGES="build-base curl-dev" \
HOME="/app" \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
#Déplacer vers le répertoire de travail
WORKDIR ${HOME}
#Copiez les fichiers nécessaires de l'hôte (fichiers sur votre ordinateur) vers Docker
ADD Gemfile ${HOME}/Gemfile
ADD Gemfile.lock ${HOME}/Gemfile.lock
RUN apk update && \
apk upgrade && \
apk add --update --no-cache ${RUNTIME_PACKAGES} && \
apk add --update --virtual build-dependencies --no-cache ${DEV_PACKAGES} && \
bundle install -j4 && \
apk del build-dependencies && \
rm -rf /usr/local/bundle/cache/* \
/usr/local/share/.cache/* \
/var/cache/* \
/tmp/* \
/usr/lib/mysqld* \
/usr/bin/mysql*
#Copiez les fichiers nécessaires de l'hôte (fichiers sur votre ordinateur) vers Docker
ADD . ${HOME}
#Ouvrir le port 3000
EXPOSE 3000
#Exécuter la commande
CMD ["bundle", "exec", "rails", "s", "puma", "-b", "0.0.0.0", "-p", "3000", "-e", "development"]
Modifier Dockerfile dans / devant
front/Dockerfile
FROM node:12.5.0-alpine
ENV HOME="/app" \
LANG=C.UTF-8 \
TZ=Asia/Tokyo
ENV HOST 0.0.0.0
WORKDIR ${HOME}
RUN apk update && \
apk upgrade && \
npm install -g n && \
yarn install &&\
rm -rf /var/cache/apk/*
#Je l'enlèverai plus tard(Lors de l'utilisation d'ECS)
#RUN yarn run build
#EXPOSE 3000
#CMD ["yarn", "dev"]
back/Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
yml:./docker-compose.yml
version: "3"
services:
db:
image: mysql:5.7
env_file:
- ./back/environments/db.env
restart: always
volumes:
- db-data:/var/lib/mysql:cached
back:
build: back/
# rm -f tmp/pids/server.Utile lorsque vous ne parvenez pas à effacer le serveur de rails avec pid
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
env_file:
- ./back/environments/db.env
volumes:
- ./back:/app:cached
depends_on:
- db
#Port de l'ordinateur hôte: port dans Docker
ports:
- 3000:3000
front:
build: front/
command: yarn run dev
volumes:
- ./front:/app:cached
ports:
#Port de l'ordinateur hôte: port dans Docker
- 8080:3000
depends_on:
- back
volumes:
public-data:
tmp-data:
log-data:
db-data:
Le réseau dans Docker est différent du réseau sur la machine hôte. Par exemple, le processus rails lancé par Docker est démarré à localhost (127.0.0.1): 3000 dans l'environnement virtuel (conteneur). Il est différent de localhost sur la machine hôte.
Cependant, il peut être résolu par le mappage de port dans docker-compose.yml.
Si vous spécifiez le port hôte 3000 et le port conteneur 3000 et que vous vous connectez à 0.0.0.0, vous pouvez accéder avec localhost comme si vous l'aviez démarré sur la machine hôte. C'est ce qu'on appelle la redirection de port.
Vous pouvez accéder au processus intégré dans l'environnement virtuel normalement en spécifiant l'adresse de liaison et en effectuant la redirection de port.
référence: La signification de l'option -b des rails s -b 0.0.0.0
Alors, que signifie 8080: 3000? Ce port mappe le port conteneur 3000 au port hôte 8080 (≒ redirection de port). En d'autres termes, le processus nuxt construit à l'intérieur du conteneur Docker utilise le port 3000, mais lorsque vous naviguez sur la machine hôte, rendez-le visible sur 8080. (Si Rails vaut également 3000, il sera dupliqué dans la machine hôte, donc une erreur se produira)
./back/db.env
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_USER=username
MYSQL_PASSWORD=userpassword
./
docker-compose build
Cela prendra du temps. Vous n'avez pas besoin de construire plusieurs fois, lancez-le simplement lorsque vous changez Gemfile ou Dockerfile! (Je l'ai fait plusieurs fois au début et j'ai perdu du temps.)
C'est la commande docker-compose qui est sortie pour la première fois, mais à partir de maintenant j'utiliserai beaucoup cette commande.
hello, Nuxt
Créer une application nuxt sous front Bonjour tout le monde avec Nuxt!
La structure finale du répertoire ressemble à ceci.
...Abréviation
front
├─Dockerfile
...Abréviation
├─components //Où placer les composants de vue
├─layouts //Où l'index appelle par défaut
├─pages //Ajouter ici lors de l'ajout d'une page
├─plugins //Où mettre le fichier de configuration du plugin à ajouter avec du fil, etc.
├─nuxt.config.js //nuxt lui-même fichier de configuration
├─package.json //Où définir la dépendance de package de yarn / npm
...Abréviation
./
docker-compose build
docker-compose run front npx [email protected]
#S'il s'agit de la version3, une erreur se produira sauf s'il s'agit d'un répertoire vide, la version est donc spécifiée.
#L'écran de sélection suivant apparaîtra.
#J'aime le nom de l'application, donc ça va!Ce sera le titre une fois ouvert sur le navigateur
? Project name --> sample_app
#J'aime la description de l'application, donc ça va!Il devient un sous-titre lorsqu'il est ouvert sur le navigateur
? Project description --> sample_app
#Créateur d'application, je l'aime donc c'est OK!
? Author name --> me
#Vous pouvez choisir npm ou yarn, mais le fil semble être plus rapide, alors sélectionnez le fil
? Choose the package manager --> Yarn
? Choose UI framework --> Vuetify.js
? Choose custom server framework --> None
? Choose Nuxt.js modules --> Axios
? Choose linting tools --> -
? Choose test framework --> None
? Choose rendering mode --> SPA
** docker-compose run **: signifie exécuter la commande suivante sur votre machine Docker ** front **: signifie exécuter sur un conteneur avec ce nom
Lorsque vous voulez taper la commande Rails
docker-compose run back rails db:create
Au fait, si vous voulez aller dans un conteneur et déboguer
docker-compose exec back sh
À
docker-compose up front
Lancez l'image de devant que vous venez de créer. http://localhost:8080/
Accédez à l'URL ci-dessus et lorsque cet écran s'affiche, c'est terminé!
hello, Rails
créer une application de rails sous le dos Bonjour le monde avec des rails! Yay!
...Abréviation
front
├─Dockerfile
├─Gemfile
├─Gemfile.lock
...Abréviation
├─app //Où le contrôleur et la vue sont inclus
├─config //Où il y a quelque chose qui est lu au démarrage
├─db //informations de table de base de données, etc.
├─environments //Variables d'environnement pour les informations de connexion à la base de données
...Abréviation
./
#Créez en mode API.--Si vous supprimez l'API, les éléments nécessaires au dessin de l'écran tels que la vue seront également installés.
#Sélectionnez MySQL comme base de données.
docker-compose run back rails new . -f -d mysql --api
docker-compose build
Dans cet état, le contenu du Gemfile a déjà été réécrit à partir de l'état initial. S'il te plaît vérifie le.
yml:./back/config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> #ajouter.
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %> #ajouter.
host: db #changement.
Accordez des autorisations à l'utilisateur décrit dans db.env.
./
touch ./back/db/grant_user.sql
sql:./back/db/grant_user.sql
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%';
FLUSH PRIVILEGES;
./
#Démarrez le conteneur.
docker-compose up
#Exécutez le SQL ci-dessus dans le conteneur db.
docker-compose exec db mysql -u root -p -e"$(cat back/db/grant_user.sql)"
#Création de DB.
docker-compose run back rails db:create
http://localhost:3000/ Accès à! Si vous voyez l'écran familier ci-dessous, vous avez réussi.
À partir de là, passons à l'implémentation. Autant que possible, j'ai facilité l'ajout de fonctions par la suite, donc Si vous souhaitez ajouter une autre nouvelle fonction, essayez-la de la même manière.
./
docker-compose run back rails g scaffold user name:string
#Il crée divers fichiers comme celui-ci.
Running via Spring preloader in process 20
invoke active_record
create db/migrate/20200902105643_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
invoke resource_route
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke test_unit
create test/controllers/users_controller_test.rb
# db/Ci-dessous migrer~create_users.Il exécute rb et crée une table dans la base de données.
#Une fois exécuté, le même fichier ne sera pas réexécuté.
# 2020~Si la partie numérique de est modifiée, elle peut être réexécutée, mais si la même table existe dans le DB, une erreur se produira.
docker-compose run back rails db:migrate
Vous avez maintenant une table appelée users dans une base de données appelée app_development. Facile!
http://localhost:3000/users/ Accédons à. Comme il est en mode API, vous devriez voir un json vide sur un écran vide.
Pourquoi l'écran ressemble-t-il à ceci? C'est, Il y a un secret dans **. / Back / config / routes.rb **.
rb:./back/config/routes.rb
Rails.application.routes.draw do
resources :users
end
Il y a une description de: utilisateurs dans les ressources. Il relie un contrôleur appelé ./back/app/users_controller.rb avec un chemin comme ** / users **. Par conséquent, il est facile de penser que la même procédure est utilisée lors de l'ajout de fonctions.
./
#Avec cette commande, vous pouvez vérifier quelle route est actuellement enregistrée.
docker-compose run back rails routes
Je vais omettre les détails, mais j'apprécierais que vous puissiez le vérifier dans le tutoriel, etc.
La communication entre nuxt et rails nécessite une certaine préparation. Ne nous précipitons pas.
Un plugin appelé axios est utilisé pour la communication API.
./
docker-compose run front yarn
docker-compose run front yarn add @nuxtjs/axios
Notez que ce qui suit a été ajouté à ./front/package.json:
json:./front/package.json
...
"@nuxtjs/axios": "^5.12.2"
...
Modifiez nuxt.config.js, qui est le fichier de configuration qui est chargé lorsque nuxt est démarré pour la première fois.
javascript:nuxt.config.js
...
modules: [
'@nuxtjs/axios' //ajouter à
],
...
Créez un nouveau fichier appelé axios.js sous ./front/plugins/.
javascript:./front/plugins/axios.js
import axios from "axios"
export default axios.create({
baseURL: "http://localhost:3000"
})
./back/Gemfile
...
gem 'rack-cors' #ajouter à
...
./
docker-compose build
Ajouter des paramètres à ./back/config/initializers/cors.rb
rb:./back/config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
methods: %i[get post put patch delete options head]
end
end
./
docker-compose up
Créons en fait un nouvel écran. Créez un nouveau users.vue sous ./front/pages.
vue:./front/pages/users.vue
<template>
<v-container>
<v-row align="center" justify="center">
<v-col cols="12">
<h1>Hello, Qiita! </h1>
</v-col>
</v-row>
<v-card
class="mx-auto"
max-width="300"
tile
>
<v-list rounded>
<v-subheader>USERS</v-subheader>
<v-list-item-group color="primary">
<v-list-item
v-for="user in users"
:key="users.id"
@click=""
>
<v-list-item-content>
<v-list-item-title v-text="user.name"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-container>
</template>
<script>
import axios from "~/plugins/axios"
export default {
data() {
return {
users: []
}
},
created() {
//Attirez les utilisateurs avec axios
axios.get("/users").then(res => {
if (res.data) {
this.users = res.data
}
})
}
}
</script>
J'ai les données Utilisateurs ci-dessus ... mais elles ne devraient rien afficher car elles ne contiennent rien. Maintenant, sauvegardons les données dans la base de données avec l'API.
vue:./front/pages/users.vue
<template>
<v-container>
<v-row align="center" justify="center">
<v-col cols="12">
<v-text-field
label="Username"
v-model="name"
prepend-icon=""
type="text"
/>
<v-btn color="primary" @click="createUser">ADD USER</v-btn>
</v-col>
<v-col cols="12">
<h1>Hello, Qiita! </h1>
</v-col>
</v-row>
<v-card
class="mx-auto"
max-width="300"
tile
>
<v-list rounded>
<v-subheader>USERS</v-subheader>
<v-list-item-group color="primary">
<v-list-item
v-for="user in users"
:key="users.id"
@click=""
>
<v-list-item-content>
<v-list-item-title v-text="user.name"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-card>
</v-container>
</template>
<script>
import axios from "~/plugins/axios"
export default {
data() {
return {
name: "",
users: []
}
},
created() {
//Attirez les utilisateurs avec axios
axios.get("/users").then(res => {
if (res.data) {
this.users = res.data
}
})
},
methods: {
//Enregistrer les utilisateurs avec axios
createUser(){
axios.post("/users", {name: this.name})
.then(res => {
if (res.data) {
this.users.push(res.data)
}
})
}
}
}
</script>
Vous pouvez maintenant enregistrer l'utilisateur. L'a fait! À propos, l'écran de nuxt devient blanc lorsque le thème sombre de nuxt.config.js est défini sur false.
Maintenant, configurons et ajoutons un test automatisé!
./back/Gemfile
...
gem 'rspec-rails' #ajouter à
gem 'factory_bot_rails' #ajouter à
...
./
docker-compose down
docker-compose build back
docker-compose up
docker-compose exec back rails generate rspec:install
#Les fichiers suivants seront ajoutés
Running via Spring preloader in process 18
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
Commencez par créer un fichier de test.
./
mkdir ./back/spec/models
mkdir ./back/spec/requests
mkdir ./back/spec/factories
touch ./back/spec/models/user_spec.rb
touch ./back/spec/requests/user_spec.rb
touch ./back/spec/factories/users.rb
rb:./back/spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
it 'Test normal' do
@user = User.new(
name: 'test'
)
expect(@user).to be_valid
end
end
rb:./back/spec/factories/users.rb
# frozen_string_literal: true
FactoryBot.define do
factory :user do
name { 'testuser' }
end
end
rb:./back/spec/requests/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :request do
# frozen_string_literal: true
require 'rails_helper'
describe 'User' do
before(:each) do
@status_code_ok = 200
end
it 'Afficher l'utilisateur' do
@user = FactoryBot.create(:user)
get '/users/'
@json = JSON.parse(response.body)
#Juger si une réponse est possible ou non
expect(response.status).to eq(@status_code_ok)
end
end
end
./
docker-compose run back bundle exec rspec
..
Finished in 0.13418 seconds (files took 2.18 seconds to load)
2 examples, 0 failures
L'a fait. Le test est réussi. Vive le bon travail.
Ensuite, laissez CircleCI tester automatiquement le test créé ci-dessus chaque fois que vous le poussez avec git!
Avez-vous créé un compte CircleCI? Si votre compte CircleCI est lié à votre compte git, comme indiqué dans l'image Vous verrez un bouton SetUp pour votre référentiel, appuyez dessus!
Appuyez sur Ajouter une configuration pour créer et générer une demande d'extraction pour ce référentiel.
Fusionnez-le dans master et tirez-le localement avec la commande git pull
.
Après l'extraction, .circleci / config.yml
a été généré avec succès localement.
Dans CircleCI, ce fichier config.yml est modifié pour contrôler les tests automatiques et le déploiement automatique.
Ajoutez ce qui suit à la partie test de database.yml.
yml:./back/config/database.yml
test:
<<: *default
database: app_test
username: root #ajouter à
password: rootpassword #ajouter à
Il est maintenant temps que CircleCI exécute les tests automatisés. Remplacez config.yml par la description suivante et poussez-le vers git.
yml:./circleci/config.yml
version: 2.1
#Tâche à exécuter
jobs:
#travail à construire
build:
machine:
image: circleci/classic:edge
steps:
- checkout
- run:
name: docker-compose build
command: docker-compose build
#travail à tester
test:
machine:
image: circleci/classic:edge
steps:
- checkout
- run:
name: docker-compose up -d
command: docker-compose up -d
- run: sleep 30
- run:
name: docker-compose run back rails db:create RAILS_ENV=test
command: docker-compose run back rails db:create RAILS_ENV=test
- run:
name: docker-compose run back rails db:migrate RAILS_ENV=test
command: docker-compose run back rails db:migrate RAILS_ENV=test
- run:
name: docker-compose run back bundle exec rspec spec
command: docker-compose run back bundle exec rspec spec
- run:
name: docker-compose down
command: docker-compose down
#Workflow pour contrôler la commande
workflows:
build_and_test_and_deploy:
jobs:
- build
- test:
requires:
- build
L'a fait! C'est un succès!
C'est tout pour les besoins de cet article. Je vous remercie pour votre travail acharné.
Je vous remercie pour votre travail acharné. Je suis désolé que ça fait si longtemps. J'ai écrit cet article avec l'espoir qu'il y aurait un article qui créerait un environnement qui pourrait être facilement développé immédiatement. Puisqu'il est lié à CircleCI, je pense que le développement piloté par les tests peut être réalisé immédiatement dans cet environnement. Ce ne sont que des exemples, donc je pense qu'il y a une meilleure structure et un meilleur style d'écriture. Dans ce cas, essayez de l'implémenter vous-même, et si vous pensez "c'est mieux!", Je vous serais reconnaissant de bien vouloir commenter.
Si j'ai le temps, je pense que je les rédigerai ensuite pour le déploiement en production à l'aide d'ECS dans l'environnement AWS. Ensuite, je pense que je vais finir d'écrire sur IaC avec terraform.
Recommended Posts