CircleCI? ?? ?? Docker ??? Die Leute sollten sich das zuerst ansehen. ↑
Studieren für das Studieren bedeutet nicht viel ... Bewegen Sie also zuerst Ihre Hände! Also werde ich dieses Mal einen Artikel im praktischen Format schreiben. Ich hoffe, dass diejenigen, die es lesen, schnell eine Entwicklungsumgebung aufbauen und sich schnell auf die Entwicklung konzentrieren können.
Ich habe es ungefähr dreimal in meiner Umgebung reproduziert, um nicht so viele Fehler wie möglich zu erleiden.
Ich denke, es wird wahrscheinlich eine Trilogie sein ... Es tut mir leid, dass es lang ist.
Erstens: Dieser Artikel 2. [[Teil 2] Mit Rails + Nuxt + MySQL + Docker erstellten WEB-Dienst mit ECS / ECR / CircleCI automatisch bereitstellen und terraformieren](https://qiita.com/Shogo1222/items/ dcbc1e50f6fc83f48b44) Drittens: [Teil 2] Stellen Sie den mit Rails + Nuxt + MySQL + Docker erstellten WEB-Dienst automatisch mit ECS / ECR / CircleCI bereit und machen Sie ihn terraform
Es ist lang, aber lasst uns unser Bestes geben!
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 installiert
Docker auf Mac installieren (Update: 13.07.2019)
--CircleCI-Konto erstellt
Ich habe gerade CircleCI gestartet und es daher leicht verständlich zusammengefasst
Ich gab git das fertige Produkt. qiita-sample-app
app //Jeder Name ist in Ordnung
├─docker-compose.yml
├─front
| ├─Dockerfile
└─back
├─Dockerfile
├─Gemfile
└─Gemfile.lock
mkdir app
cd app //Gehe zur App
mkdir front //Frontkreation
mkdir back //zurück Schöpfung
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
Bearbeiten Sie die Docker-Datei in / zurück
back/Dockerfile
#Angeben eines Bildes
FROM ruby:2.6.3-alpine3.10
#Laden Sie die erforderlichen Pakete herunter
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
#Wechseln Sie in das Arbeitsverzeichnis
WORKDIR ${HOME}
#Kopieren Sie die erforderlichen Dateien vom Host (Dateien auf Ihrem Computer) nach 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*
#Kopieren Sie die erforderlichen Dateien vom Host (Dateien auf Ihrem Computer) nach Docker
ADD . ${HOME}
#Öffnen Sie den Port 3000
EXPOSE 3000
#Befehl ausführen
CMD ["bundle", "exec", "rails", "s", "puma", "-b", "0.0.0.0", "-p", "3000", "-e", "development"]
Bearbeiten Sie die Docker-Datei in / front
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/*
#Ich werde es später entfernen(Bei Verwendung von 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.Nützlich, wenn Sie den Rails-Server nicht mit pid löschen können
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
#Host-Computer-Port: Port in Docker
ports:
- 3000:3000
front:
build: front/
command: yarn run dev
volumes:
- ./front:/app:cached
ports:
#Host-Computer-Port: Port in Docker
- 8080:3000
depends_on:
- back
volumes:
public-data:
tmp-data:
log-data:
db-data:
Das Netzwerk in Docker unterscheidet sich vom Netzwerk auf dem Hostcomputer. Beispielsweise wird der von Docker gestartete Rails-Prozess unter localhost (127.0.0.1): 3000 in der virtuellen Umgebung (Container) gestartet. Es unterscheidet sich von localhost auf dem Host-Computer.
Es kann jedoch durch Portzuordnung in docker-compose.yml gelöst werden.
Wenn Sie Host-Port 3000 und Container-Port 3000 angeben und an 0.0.0.0 binden, können Sie mit localhost so zugreifen, als hätten Sie es auf dem Host-Computer gestartet. Dies wird als Portweiterleitung bezeichnet.
Sie können auf den in der virtuellen Umgebung erstellten Prozess normalerweise zugreifen, indem Sie die Bindungsadresse angeben und die Portweiterleitung durchführen.
Referenz: Die Bedeutung der Option -b der Schienen s -b 0.0.0.0
Was bedeutet 8080: 3000? Dieser Port ordnet den Container-Port 3000 dem Host-Port 8080 zu (≒ Port-Weiterleitung). Mit anderen Worten, der im Docker-Container erstellte Nuxt-Prozess verwendet Port 3000, macht ihn jedoch beim Surfen auf dem Host-Computer auf 8080 sichtbar. (Wenn Rails ebenfalls 3000 ist, wird es auf dem Host-Computer dupliziert, sodass ein Fehler auftritt.)
./back/db.env
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_USER=username
MYSQL_PASSWORD=userpassword
./
docker-compose build
Es wird einige Zeit in Anspruch nehmen. Sie müssen nicht viele Male erstellen, sondern nur ausführen, wenn Sie Gemfile oder Dockerfile ändern! (Ich habe es am Anfang oft gemacht und Zeit verloren.)
Dies ist der Docker-Compose-Befehl, der zum ersten Mal veröffentlicht wurde, aber von nun an werde ich diesen Befehl häufig verwenden.
hello, Nuxt
Erstellen Sie eine Nuxt-App unter der Vorderseite Hallo Welt mit Nuxt!
Die endgültige Verzeichnisstruktur sieht folgendermaßen aus.
...Abkürzung
front
├─Dockerfile
...Abkürzung
├─components //Wo werden die Vue-Komponenten platziert?
├─layouts //Wo Indexaufrufe standardmäßig
├─pages //Fügen Sie hier hinzu, wenn Sie eine Seite hinzufügen
├─plugins //Wo soll die Einstellungsdatei des Plugins abgelegt werden, das mit Garn usw. hinzugefügt werden soll?
├─nuxt.config.js //nuxt selbst Konfigurationsdatei
├─package.json //Wo soll die Paketabhängigkeit von Garn / npm eingestellt werden?
...Abkürzung
./
docker-compose build
docker-compose run front npx [email protected]
#Wenn es sich um Version 3 handelt, tritt ein Fehler auf, es sei denn, es handelt sich um ein leeres Verzeichnis. Daher wird die Version angegeben.
#Der folgende Auswahlbildschirm wird angezeigt.
#Ich mag den Namen der App, also ist es OK!Dies ist der Titel, wenn er im Browser geöffnet wird
? Project name --> sample_app
#Ich mag die Beschreibung der App, also ist es OK!Beim Öffnen im Browser wird es zu einem Untertitel
? Project description --> sample_app
#App Creator, ich mag es, also ist es OK!
? Author name --> me
#Sie können npm oder Garn wählen, aber Garn scheint schneller zu sein, also wählen Sie Garn
? 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-Lauf **: bedeutet, dass Sie den folgenden Befehl auf Ihrem Docker-Computer ausführen ** front **: bedeutet auf einem Container mit diesem Namen laufen
Wenn Sie den Befehl Rails eingeben möchten
docker-compose run back rails db:create
Übrigens, wenn Sie in einen Container gehen und debuggen möchten
docker-compose exec back sh
Zu
docker-compose up front
Starten Sie das gerade erstellte Front-Image. http://localhost:8080/
Greifen Sie auf die obige URL zu und wenn dieser Bildschirm angezeigt wird, ist er abgeschlossen!
hello, Rails
Erstelle eine Rails App unter back Hallo Welt mit Schienen! Yay!
...Abkürzung
front
├─Dockerfile
├─Gemfile
├─Gemfile.lock
...Abkürzung
├─app //Wo Controller und Ansicht enthalten sind
├─config //Wo gibt es etwas, das beim Start gelesen wird
├─db //DB-Tabelleninformationen usw.
├─environments //Umgebungsvariablen für DB-Verbindungsinformationen
...Abkürzung
./
#Im API-Modus erstellen.--Wenn Sie die API entfernen, werden auch die für die Bildschirmzeichnung erforderlichen Elemente wie die Ansicht installiert.
#Wählen Sie MySQL als Datenbank.
docker-compose run back rails new . -f -d mysql --api
docker-compose build
In diesem Zustand wurde der Inhalt der Gemfile bereits vom Ausgangszustand aus neu geschrieben. Überprüfen Sie bitte das.
yml:./back/config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV.fetch('MYSQL_USER') { 'root' } %> #hinzufügen.
password: <%= ENV.fetch('MYSQL_PASSWORD') { 'password' } %> #hinzufügen.
host: db #Veränderung.
Erteilen Sie dem in db.env beschriebenen Benutzer Berechtigungen.
./
touch ./back/db/grant_user.sql
sql:./back/db/grant_user.sql
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%';
FLUSH PRIVILEGES;
./
#Starten Sie den Container.
docker-compose up
#Führen Sie die obige SQL im Datenbankcontainer aus.
docker-compose exec db mysql -u root -p -e"$(cat back/db/grant_user.sql)"
#DB-Erstellung.
docker-compose run back rails db:create
http://localhost:3000/ Zugriff auf! Wenn Sie den bekannten Bildschirm unten sehen, sind Sie erfolgreich.
Von hier aus gehen wir zur Implementierung über. So weit wie möglich habe ich es einfach gemacht, danach Funktionen hinzuzufügen Wenn Sie eine weitere neue Funktion hinzufügen möchten, versuchen Sie es auf die gleiche Weise.
./
docker-compose run back rails g scaffold user name:string
#Es werden verschiedene Dateien wie diese erstellt.
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/Unten migrieren~create_users.Es führt rb aus und erstellt eine Tabelle in der DB.
#Einmal ausgeführt, wird dieselbe Datei nicht erneut ausgeführt.
# 2020~Wenn der Nummernteil von geändert wird, kann er erneut ausgeführt werden. Wenn jedoch dieselbe Tabelle in der Datenbank vorhanden ist, tritt ein Fehler auf.
docker-compose run back rails db:migrate
Jetzt haben Sie eine Tabelle mit dem Namen users in einer Datenbank mit dem Namen app_development. Einfach!
http://localhost:3000/users/ Lassen Sie uns auf zugreifen. Da es sich im API-Modus befindet, sollte auf einem leeren Bildschirm ein leerer JSON angezeigt werden.
Warum sieht der Bildschirm so aus? das ist, In **. / Back / config / route.rb ** steckt ein Geheimnis.
rb:./back/config/routes.rb
Rails.application.routes.draw do
resources :users
end
Es gibt eine Beschreibung von: Benutzern in Ressourcen. Es verknüpft einen Controller namens ./back/app/users_controller.rb mit einem Pfad wie ** / users **. Daher ist es leicht zu glauben, dass beim Hinzufügen von Funktionen dasselbe Verfahren angewendet wird.
./
#Mit diesem Befehl können Sie überprüfen, welche Route aktuell registriert ist.
docker-compose run back rails routes
Ich werde die Details weglassen, aber ich würde es begrüßen, wenn Sie es im Tutorial usw. überprüfen könnten.
Die Kommunikation von Nuxt zu Rails erfordert einige Vorbereitungen. Lass uns nicht eilen.
Für die API-Kommunikation wird ein Plugin namens Axios verwendet.
./
docker-compose run front yarn
docker-compose run front yarn add @nuxtjs/axios
Beachten Sie, dass Folgendes zu ./front/package.json hinzugefügt wurde:
json:./front/package.json
...
"@nuxtjs/axios": "^5.12.2"
...
Ändern Sie nuxt.config.js. Dies ist die Konfigurationsdatei, die beim ersten Start von nuxt geladen wird.
javascript:nuxt.config.js
...
modules: [
'@nuxtjs/axios' //hinzufügen
],
...
Erstellen Sie eine neue Datei mit dem Namen axios.js unter ./front/plugins/.
javascript:./front/plugins/axios.js
import axios from "axios"
export default axios.create({
baseURL: "http://localhost:3000"
})
./back/Gemfile
...
gem 'rack-cors' #hinzufügen
...
./
docker-compose build
Fügen Sie Einstellungen zu ./back/config/initializers/cors.rb hinzu
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
Lassen Sie uns tatsächlich einen neuen Bildschirm erstellen. Erstellen Sie unter ./front/pages eine neue users.vue.
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() {
//Holen Sie sich Benutzer mit Axios
axios.get("/users").then(res => {
if (res.data) {
this.users = res.data
}
})
}
}
</script>
Ich habe die Benutzerdaten oben erhalten ... aber sie sollten nichts anzeigen, da sie nichts enthalten. Speichern wir nun die Daten mit der API in der Datenbank.
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() {
//Holen Sie sich Benutzer mit Axios
axios.get("/users").then(res => {
if (res.data) {
this.users = res.data
}
})
},
methods: {
//Registrieren Sie Benutzer bei axios
createUser(){
axios.post("/users", {name: this.name})
.then(res => {
if (res.data) {
this.users.push(res.data)
}
})
}
}
}
</script>
Sie können den Benutzer jetzt registrieren. Erledigt! Übrigens wird der Bildschirm von nuxt weiß, wenn das dunkle Thema in nuxt.config.js auf false gesetzt ist.
Jetzt richten wir einen automatisierten Test ein und fügen ihn hinzu!
./back/Gemfile
...
gem 'rspec-rails' #hinzufügen
gem 'factory_bot_rails' #hinzufügen
...
./
docker-compose down
docker-compose build back
docker-compose up
docker-compose exec back rails generate rspec:install
#Die folgenden Dateien werden hinzugefügt
Running via Spring preloader in process 18
create .rspec
create spec
create spec/spec_helper.rb
create spec/rails_helper.rb
Erstellen Sie zunächst eine Testdatei.
./
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 'Normaler Test' 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 'Benutzer anzeigen' do
@user = FactoryBot.create(:user)
get '/users/'
@json = JSON.parse(response.body)
#Beurteilung, ob eine Antwort möglich ist oder nicht
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
Erledigt. Der Test ist erfolgreich. Ist Prost auf gute Arbeit.
Lassen Sie CircleCI als Nächstes den oben erstellten Test jedes Mal automatisch testen, wenn Sie ihn mit git drücken!
Haben Sie ein CircleCI-Konto erstellt? Wenn Ihr CircleCI-Konto mit Ihrem Git-Konto verknüpft ist, wie in der Abbildung gezeigt Sie sehen eine SetUp-Schaltfläche für Ihr Repository, drücken Sie darauf!
Klicken Sie auf Konfiguration hinzufügen, um eine Pull-Anforderung für dieses Repository zu erstellen und zu erstellen.
Füge es in master zusammen und ziehe es lokal mit dem Befehl git pull
.
Nach dem Ziehen wurde .circleci / config.yml
erfolgreich lokal generiert.
In CircleCI wird diese config.yml bearbeitet, um das automatische Testen und die automatische Bereitstellung zu steuern.
Fügen Sie dem Testteil von database.yml Folgendes hinzu.
yml:./back/config/database.yml
test:
<<: *default
database: app_test
username: root #hinzufügen
password: rootpassword #hinzufügen
Jetzt ist es Zeit, CircleCI dazu zu bringen, die automatisierten Tests durchzuführen. Überschreiben Sie config.yml mit der folgenden Beschreibung und drücken Sie es auf git.
yml:./circleci/config.yml
version: 2.1
#Job zum Ausführen
jobs:
#Job zu bauen
build:
machine:
image: circleci/classic:edge
steps:
- checkout
- run:
name: docker-compose build
command: docker-compose build
#Job zu testen
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 zur Steuerung der Bestellung
workflows:
build_and_test_and_deploy:
jobs:
- build
- test:
requires:
- build
Erledigt! Es ist ein Erfolg!
Das ist alles für den Zweck dieses Artikels. Danke für deine harte Arbeit.
Danke für deine harte Arbeit. Es tut mir leid, dass es so lange her ist. Ich schrieb diesen Artikel mit der Hoffnung, dass es einen Artikel geben würde, der eine Umgebung schaffen würde, die leicht sofort entwickelt werden könnte. Da es mit CircleCI verknüpft ist, denke ich, dass eine testgetriebene Entwicklung in dieser Umgebung sofort durchgeführt werden kann. Dies sind nur Beispiele, daher denke ich, dass es eine bessere Struktur und einen besseren Schreibstil gibt. Versuchen Sie in diesem Fall, es selbst zu implementieren, und wenn Sie der Meinung sind, dass dies besser ist, wäre ich Ihnen dankbar, wenn Sie einen Kommentar abgeben könnten.
Wenn ich Zeit habe, werde ich diese als nächstes für die Produktionsbereitstellung mit ECS in der AWS-Umgebung aufschreiben. Als nächstes denke ich, dass ich das Schreiben mit Terraform an IaC beenden werde.
Recommended Posts